# Factory Method

A factory method makes an object for you, so the code that uses it doesn't name the class it gets. A simple factory picks the class in one switch, instead of in every caller; the Gang of Four's Factory Method lets each subclass decide what to create. ASP.NET Core's registrations with a lambda are factories too.

Journeyman · C# · OOP · Updated November 3, 2026

## After this lesson you can

- Hide which class is created behind a factory method

## Key takeaways

- A factory method makes an object for its callers, so they ask for an `INotifier` and never say `new EmailNotifier()`.
- A simple factory keeps the `switch` that picks the class in one place, so a new channel is one new class and one new line.
- In the Gang of Four's Factory Method, a base class does the work, and an `abstract` method lets each subclass decide what to create.
- `AddScoped<IUserDao>(_ => new UserDao(connectionString))` is a factory: ASP.NET Core calls the lambda whenever a controller needs an `IUserDao`.

Northwind sends an order confirmation, by email or by text message, whichever the customer chose. Two classes do the sending, behind one interface:

```csharp
INotifier notifier = new EmailNotifier();
Console.WriteLine(notifier.Send("Your order 10248 has shipped."));

notifier = new TextNotifier();
Console.WriteLine(notifier.Send("Your order 10248 has shipped."));

public interface INotifier
{
    string Send(string message);
}

public class EmailNotifier : INotifier
{
    public string Send(string message) => $"Email: {message}";
}

public class TextNotifier : INotifier
{
    public string Send(string message) => $"Text: {message}";
}
```

```text
Email: Your order 10248 has shipped.
Text: Your order 10248 has shipped.
```

## The problem

Somewhere, code has to decide which class to create. Left alone, that decision ends up wherever a notifier is needed:

```csharp
INotifier notifier;
if (customer.Channel == "email")
{
    notifier = new EmailNotifier();
}
else
{
    notifier = new TextNotifier();
}
```

The order page has that `if`. So do the shipping code and the password reset. When a third channel arrives, an app notification, you must find and change every copy, and missing one is a bug.

## A factory method

A **factory method** is a method whose job is to **make an object**. The decision moves into one place:

```csharp
INotifier notifier = NotifierFactory.Create("email");
Console.WriteLine(notifier.Send("Your order 10248 has shipped."));

Console.WriteLine(NotifierFactory.Create("text").Send("Your table is ready."));

try
{
    NotifierFactory.Create("pigeon");
}
catch (ArgumentException e)
{
    Console.WriteLine(e.Message);
}

public static class NotifierFactory
{
    public static INotifier Create(string channel) => channel switch
    {
        "email" => new EmailNotifier(),
        "text" => new TextNotifier(),
        _ => throw new ArgumentException($"There's no notifier for {channel}.")
    };
}

public interface INotifier
{
    string Send(string message);
}

public class EmailNotifier : INotifier
{
    public string Send(string message) => $"Email: {message}";
}

public class TextNotifier : INotifier
{
    public string Send(string message) => $"Text: {message}";
}
```

```text
Email: Your order 10248 has shipped.
Text: Your table is ready.
There's no notifier for pigeon.
```

- The callers ask for **an `INotifier`**, and never say `new EmailNotifier()`. They don't know, or care, which class they get.
- The `switch` lives in **one** place. A new channel is one new class and one new line.
- An unknown channel fails loudly, in one place, with a clear message.

This "simple factory" is the version you'll write most often.

## The Gang of Four's Factory Method

The Gang of Four's **Factory Method** pattern goes one step further: a base class does the work, and leaves **one** decision, what to create, to its subclasses.

```csharp
OrderConfirmation confirmation = new EmailConfirmation();
Console.WriteLine(confirmation.Confirm(10248));

confirmation = new TextConfirmation();
Console.WriteLine(confirmation.Confirm(10249));

public abstract class OrderConfirmation
{
    // The factory method: each subclass decides which notifier to make.
    protected abstract INotifier CreateNotifier();

    public string Confirm(int orderId)
    {
        INotifier notifier = CreateNotifier();
        return notifier.Send($"Thanks! Order {orderId} is confirmed.");
    }
}

public class EmailConfirmation : OrderConfirmation
{
    protected override INotifier CreateNotifier() => new EmailNotifier();
}

public class TextConfirmation : OrderConfirmation
{
    protected override INotifier CreateNotifier() => new TextNotifier();
}

public interface INotifier
{
    string Send(string message);
}

public class EmailNotifier : INotifier
{
    public string Send(string message) => $"Email: {message}";
}

public class TextNotifier : INotifier
{
    public string Send(string message) => $"Text: {message}";
}
```

```text
Email: Thanks! Order 10248 is confirmed.
Text: Thanks! Order 10249 is confirmed.
```

- **`Confirm`** is written once, in the base class: it makes a notifier, and sends the message.
- **`CreateNotifier`** is the **factory method**: `abstract`, so each subclass must say what to create.
- It's polymorphism, as in *Adding Abstraction*: the base class calls a method, and the subclass's version runs.

Use the simple factory when one method can choose. Use the subclass version when the classes doing the work differ in more than one way, and the "what to create" is one of those ways.

## You've used factories already

In `Program.cs`, this registration is a factory:

```csharp
builder.Services.AddScoped<IUserDao>(_ => new UserDao(connectionString));
```

The lambda is a factory method. ASP.NET Core calls it whenever a controller needs an `IUserDao`, and the controller never says `new UserDao(...)`. In the tests, a different factory hands out a `FakeUserDao`, and the controller can't tell the difference. That's the whole point of the pattern.

## Check yourself

1 question to try on the lesson page.

## So what

A factory method makes objects so callers don't have to name their classes. Put the choice in one place, as a simple factory, or let subclasses make it, as the Gang of Four's Factory Method, and adding a new kind becomes one class and one line.

## Key terms

- [Factory Pattern](https://www.ask-codey.com/glossary/factory-pattern)
- [Factory Method](https://www.ask-codey.com/glossary/factory-method)

## Cheat sheets

- [Factory Method](https://www.ask-codey.com/cheat-sheets/design-patterns-factory-method-cheat-sheet)

Source: https://www.ask-codey.com/lessons/design-patterns-factory-method
