Abstract Factory Pattern in C# – Step-by-Step Tutorial.
In this tutorial, I’ll explain how I implemented the Abstract Factory Pattern in C# using my project:
GitHub Repository: https://github.com/stevsharp/AbstractFactoryDemo
This project demonstrates how to support multiple database providers like:
Each database needs related objects such as:
- Database Connection
- Database Command
Instead of hardcoding these objects directly, we use the Abstract Factory Pattern to make the code cleaner and scalable.
Step 1: The Problem
Imagine your application supports multiple databases.
Without using Abstract Factory, your code may look like this:
if(databaseType == "SQL")
{
var connection = new SqlConnection();
var command = new SqlCommand();
}
else
{
var connection = new MySqlConnection();
var command = new MySqlCommand();
}
Why this is bad:
- Too many
if/else statements
- Hard to maintain
- Difficult to scale
- Tight coupling with concrete classes
We need a better approach.
Step 2: Create Abstract Products
These interfaces define common behavior for all database implementations.
IDbConnection.cs
public interface IDbConnection
{
void Connect();
}
IDbCommand.cs
public interface IDbCommand
{
void Execute();
}
Now every database provider must implement these interfaces.
Step 3: Create SQL Server Products
SqlConnection.cs
public class SqlConnection : IDbConnection
{
public void Connect()
{
Console.WriteLine("Connecting to SQL Server...");
}
}
SqlCommand.cs
public class SqlCommand : IDbCommand
{
public void Execute()
{
Console.WriteLine("Executing SQL command...");
}
}
These classes handle SQL Server operations.
Step 4: Create MySQL Products
MySqlConnection.cs
public class MySqlConnection : IDbConnection
{
public void Connect()
{
Console.WriteLine("Connecting to MySQL...");
}
}
MySqlCommand.cs
public class MySqlCommand : IDbCommand
{
public void Execute()
{
Console.WriteLine("Executing MySQL command...");
}
}
These classes handle MySQL operations.
Step 5: Create the Abstract Factory
Now we create a factory interface.
IDatabaseFactory.cs
public interface IDatabaseFactory
{
IDbConnection CreateConnection();
IDbCommand CreateCommand();
}
This ensures every factory creates:
- Connection objects
- Command objects
Step 6: Create SQL Server Factory
SqlServerFactory.cs
public class SqlServerFactory : IDatabaseFactory
{
public IDbConnection CreateConnection()
{
return new SqlConnection();
}
public IDbCommand CreateCommand()
{
return new SqlCommand();
}
}
This factory creates SQL-related objects.
Step 7: Create MySQL Factory
MySqlFactory.cs
public class MySqlFactory : IDatabaseFactory
{
public IDbConnection CreateConnection()
{
return new MySqlConnection();
}
public IDbCommand CreateCommand()
{
return new MySqlCommand();
}
}
This factory creates MySQL-related objects.
Step 8: Use the Factory in Client Code
Now the client works with the factory instead of concrete classes.
Program.cs
class Program
{
static void Main()
{
IDatabaseFactory factory = new MySqlFactory();
var connection = factory.CreateConnection();
var command = factory.CreateCommand();
connection.Connect();
command.Execute();
}
}
Output
Connecting to MySQL...
Executing MySQL command...
Step 9: Why This Pattern Is Useful
Let’s say your application needs to support PostgreSQL in the future.
You would simply add:
- PostgresConnection
- PostgresCommand
- PostgresFactory
And your client code stays exactly the same.
That makes your code:
✅ Flexible
✅ Maintainable
✅ Scalable
✅ Easy to test
Visual Flow
Client
↓
IDatabaseFactory
↓
--------------------------------
↓ ↓
SqlServerFactory MySqlFactory
↓ ↓
SqlConnection MySqlConnection
SqlCommand MySqlCommand
Real Interview Explanation
Here’s how you can explain this in an interview:
In this project, I used the Abstract Factory Pattern to create families of related database objects. Each database provider creates its own connection and command objects. This reduces tight coupling and makes the application easier to extend when adding new databases.
When Should You Use Abstract Factory?
Use Abstract Factory when:
- You need to create families of related objects
- You want loose coupling
- Your system supports multiple implementations
- You want easier scalability
Examples:
- Database providers
- UI themes
- Payment gateways
- Cloud providers
Final Thoughts
Abstract Factory is a great design pattern when your application needs flexibility.
Instead of hardcoding object creation logic everywhere, you centralize it through factories and keep your code clean.
If you want to see the full implementation, check out the repository:
https://github.com/stevsharp/AbstractFactoryDemo
Reference
https://refactoring.guru/design-patterns/abstract-factory