C# - Design Pattern - Abstract Factory

main program

Product Interfaces (the abstract products)


public interface IDbConnection
{
    void Connect();
}

public interface IDbCommand
{
    void Execute(string sql);
}

public interface IDataReader
{
    void Read();
}

Concrete Products: SQL Server Family



public class SqlServerConnection : IDbConnection
{
    public void Connect() => Console.WriteLine("Connecting to SQL Server...");
}

public class SqlServerCommand : IDbCommand
{
    public void Execute(string sql) =>
        Console.WriteLine($"Executing SQL Server query: {sql}");
}

public class SqlServerDataReader : IDataReader
{
    public void Read() => Console.WriteLine("Reading SQL Server data...");
}

Concrete Products: MySQL Family

  

public class MySqlConnection : IDbConnection
{
    public void Connect() => Console.WriteLine("Connecting to MySQL...");
}

public class MySqlCommand : IDbCommand
{
    public void Execute(string sql) =>
        Console.WriteLine($"Executing MySQL query: {sql}");
}

public class MySqlDataReader : IDataReader
{
    public void Read() => Console.WriteLine("Reading MySQL data...");
}

The Abstract Factory

  
      
public interface IDatabaseFactory
{
    IDbConnection CreateConnection();
    IDbCommand CreateCommand();
    IDataReader CreateDataReader();
}

Concrete Factories


public class SqlServerFactory : IDatabaseFactory
{
    public IDbConnection CreateConnection() => new SqlServerConnection();
    public IDbCommand CreateCommand() => new SqlServerCommand();
    public IDataReader CreateDataReader() => new SqlServerDataReader();
}

public class MySqlFactory : IDatabaseFactory
{
    public IDbConnection CreateConnection() => new MySqlConnection();
    public IDbCommand CreateCommand() => new MySqlCommand();
    public IDataReader CreateDataReader() => new MySqlDataReader();
}

Client Code (depends only on the abstract factory)

  

public class DatabaseClient
{
    private readonly IDbConnection _connection;
    private readonly IDbCommand _command;
    private readonly IDataReader _reader;

    public DatabaseClient(IDatabaseFactory factory)
    {
        _connection = factory.CreateConnection();
        _command    = factory.CreateCommand();
        _reader     = factory.CreateDataReader();
    }

    public void Run()
    {
        _connection.Connect();
        _command.Execute("SELECT * FROM Users");
        _reader.Read();
    }
}

Usage



class Program
{
    static void Main()
    {
        // Choose the database provider dynamically
        IDatabaseFactory factory = new SqlServerFactory();
        // Or: IDatabaseFactory factory = new MySqlFactory();

        var client = new DatabaseClient(factory);
        client.Run();
    }
}