Complete API documentation for the Abstract Factory pattern in PatternKit.
Namespace
using PatternKit.Creational.AbstractFactory;
AbstractFactory<TKey>
Creates families of related objects by key.
public sealed class AbstractFactory<TKey> where TKey : notnull
Type Parameters
Parameter
Description
TKey
The type of key used to identify product families
Methods
Method
Returns
Description
GetFamily(TKey key)
ProductFamily
Gets a product family by key
TryGetFamily(TKey key, out ProductFamily family)
bool
Attempts to get a family; returns false if not found
HasFamily(TKey key)
bool
Checks if a family is registered for the key
Properties
Property
Type
Description
FamilyKeys
IEnumerable<TKey>
All registered family keys
Static Methods
Method
Returns
Description
Create()
Builder
Creates a new fluent builder
Create(IEqualityComparer<TKey> comparer)
Builder
Creates a builder with custom key comparer
Exceptions
Method
Exception
Condition
GetFamily
KeyNotFoundException
Key not registered and no default exists
Example
var factory = AbstractFactory<string>.Create()
.Family("light")
.Product<IButton>(() => new LightButton())
.Product<ITextBox>(() => new LightTextBox())
.Family("dark")
.Product<IButton>(() => new DarkButton())
.Product<ITextBox>(() => new DarkTextBox())
.Build();
// Get family and create products
var lightFamily = factory.GetFamily("light");
var button = lightFamily.Create<IButton>();
// Safe access
if (factory.TryGetFamily("custom", out var custom))
{
var textBox = custom.Create<ITextBox>();
}
// Check availability
bool hasDark = factory.HasFamily("dark"); // true
AbstractFactory<TKey>.Builder
Fluent builder for configuring product families.
public sealed class Builder
Methods
Method
Returns
Description
Family(TKey key)
Builder
Starts or switches to a product family
Product<TProduct>(Func<TProduct> creator)
Builder
Registers a product creator for current family
DefaultFamily()
Builder
Starts the default family definition
DefaultProduct<TProduct>(Func<TProduct> creator)
Builder
Registers a product creator for default family
Build()
AbstractFactory<TKey>
Builds the immutable factory
Exceptions
Method
Exception
Condition
Product<TProduct>
InvalidOperationException
Called before Family()
Example
var factory = AbstractFactory<Theme>.Create()
// First family
.Family(Theme.Light)
.Product<IButton>(() => new LightButton())
.Product<IDialog>(() => new LightDialog())
// Second family
.Family(Theme.Dark)
.Product<IButton>(() => new DarkButton())
.Product<IDialog>(() => new DarkDialog())
// Default for unknown keys
.DefaultFamily()
.DefaultProduct<IButton>(() => new DefaultButton())
.DefaultProduct<IDialog>(() => new DefaultDialog())
.Build();
AbstractFactory<TKey>.ProductFamily
Represents a family of related products.
public sealed class ProductFamily
Methods
Method
Returns
Description
Create<TProduct>()
TProduct
Creates a product of the specified type
TryCreate<TProduct>(out TProduct product)
bool
Attempts to create a product; returns false if not registered
CanCreate<TProduct>()
bool
Checks if a product type is registered
Exceptions
Method
Exception
Condition
Create<TProduct>
InvalidOperationException
Product type not registered in family
Example
var family = factory.GetFamily("light");
// Direct creation (throws if not registered)
var button = family.Create<IButton>();
// Safe creation
if (family.TryCreate<IAdvancedButton>(out var advanced))
{
advanced.DoAdvancedThing();
}
// Capability check
if (family.CanCreate<IDialog>())
{
var dialog = family.Create<IDialog>();
dialog.Show("Title", "Message");
}
Thread Safety
Component
Thread-Safe
Builder
No - use from single thread during configuration
AbstractFactory<TKey>
Yes - immutable after build
ProductFamily
Yes - immutable after build
Type Constraints
Constraint
Location
Purpose
TKey : notnull
AbstractFactory<TKey>
Keys must not be null
Complete Example
using PatternKit.Creational.AbstractFactory;
// Product interfaces
public interface IButton { string Render(); void Click(); }
public interface ITextBox { string Render(); string Text { get; set; } }
public interface ICheckBox { string Render(); bool IsChecked { get; set; } }
// Platform enum
public enum Platform { Windows, MacOS, Linux }
// Create the factory
var uiFactory = AbstractFactory<Platform>.Create()
.Family(Platform.Windows)
.Product<IButton>(() => new WindowsButton())
.Product<ITextBox>(() => new WindowsTextBox())
.Product<ICheckBox>(() => new WindowsCheckBox())
.Family(Platform.MacOS)
.Product<IButton>(() => new MacButton())
.Product<ITextBox>(() => new MacTextBox())
.Product<ICheckBox>(() => new MacCheckBox())
.Family(Platform.Linux)
.Product<IButton>(() => new LinuxButton())
.Product<ITextBox>(() => new LinuxTextBox())
.Product<ICheckBox>(() => new LinuxCheckBox())
.Build();
// Usage: Platform-agnostic UI construction
void CreateLoginForm(Platform platform)
{
var widgets = uiFactory.GetFamily(platform);
var usernameBox = widgets.Create<ITextBox>();
var passwordBox = widgets.Create<ITextBox>();
var rememberMe = widgets.Create<ICheckBox>();
var loginButton = widgets.Create<IButton>();
usernameBox.Text = "Enter username";
passwordBox.Text = "";
rememberMe.IsChecked = false;
Console.WriteLine(usernameBox.Render());
Console.WriteLine(passwordBox.Render());
Console.WriteLine(rememberMe.Render());
Console.WriteLine(loginButton.Render());
}
// Enumerate all families
foreach (var key in uiFactory.FamilyKeys)
{
Console.WriteLine($"Platform: {key}");
var family = uiFactory.GetFamily(key);
Console.WriteLine($" Has Button: {family.CanCreate<IButton>()}");
Console.WriteLine($" Has TextBox: {family.CanCreate<ITextBox>()}");
}