Factory method in C# Core

csharp wallpaper

The factory method in C# Core is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. We can create objects by calling a factory method – either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes – rather than by calling a constructor.

Intent

  • Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses
  • Defining a “virtual” constructor
  • The new operator considered harmful

Problem

A framework needs to standardize the architectural model for a range of applications, but allow for individual applications to define their own domain objects and provide for their instantiation.

Explanation

Factory Method is to creating objects as Template Method is to implementing an algorithm. A superclass specifies all standard and generic behaviour (using pure virtual “placeholders” for creation steps). Then delegates the creation details to subclasses that are supplied by the client.

Then, it makes a design more customizable and only a little more complicated. Other design patterns require new classes, whereas Factory Method only requires a new operation.

People often use Factory Method as the standard way to create objects; but it isn’t necessary if: the class that’s instantiated never changes, or instantiation takes place in an operation that subclasses can easily override (such as an initialization operation).

This method is similar to Abstract Factory but without the emphasis on families.

Factory Methods are routinely specified by an architectural framework, and then implemented by the user of the framework.

Participants

So, the classes and/or objects participating in this pattern are:

  • Product (Page)
    • defines the interface of objects the factory method creates
  • ConcreteProduct (SkillsPage, EducationPage, ExperiencePage)
    • implements the Product interface
  • Creator (Document)
    • declares the factory method, which returns an object of type Product. Creator may also define a default implementation of the factory method that returns a default ConcreteProduct object
    • may call the factory method to create a Product object.
  • ConcreteCreator (Report, Resume)
    • overrides the factory method to return an instance of a ConcreteProduct
Factory method in C#/.NET Core
Factory method

Implementation

Now, after a lot of words, the implementation of a factory method in C# Core. The source code of those examples are on GitHub.

Structural Code Sample

The structural code demonstrates the Factory method offering great flexibility in creating different objects. The Abstract class may provide a default object, but each subclass can instantiate an extended version of the object.

Project name: Factory.Structural

Real-world Code Sample

The real-world code demonstrates the Factory method offering flexibility in creating different documents. The derived Document classes, Report and Resume, instantiate extended versions of the Document class. Here, the Factory Method is called in the constructor of the Document base class.

Project name: Factory.RealWorld

.NET Optimized Code Sample

The .NET optimized code demonstrates the same functionality as the real-world example but uses more modern, built-in .NET features. Both the fixed size Document array and the Pages ArrayList have been replaced with type-safe generic List collections. .NET language features in this example include automatic properties and collection initialization which significantly reduce the number of lines of code.

Project name: Factory.NetOptimized

Factory Method, when and where you would use it

Class constructors exist so that clients can create instances of a class. However, there are situations, where the client does not, or should not, know which one of several candidate classes to instantiate. The Factory Method allows the client to use an interface for creating an object while still retaining control over which class to instantiate.

The key objective of the Factory Method is extensibility. Factory Methods are common in applications that manage, maintain, or manipulate collections of objects that are different but at the same time have many characteristics in common.

A document management system, for example, is more extensible by referencing the documents as a collection of IDocuments. These documents may be Text files, Word documents, PowerPoint presentations, or legal papers. They are different but each one has an author, a title, a type, a size, a location, a page count, etc.

When a new document type is introduced it simply implements the IDocument interface and it will work like all other documents. To support this new document type, the Factory Method may or may not have to be adjusted (depending on how it was implemented, i.e. with or without parameters). The switch-case statement in the example below would need adjustment.

public class DocumentFactory
{
    // Factory method with parameter
    public IDocument CreateDocument(DocumentType docType)
    {
        IDocument document = null;
        switch (docType)
        {
            case DocumentType.Word:
                document = new WordDocument();
                break;
            case DocumentType.Excel:
                document = new ExcelDocument();
                break;
            case DocumentType.PowerPoint:
                document = new PowerPointDocument();
                break;
        }
        return document;
    }
}

Usually, we are using Factory Methods in ‘manager’ type components, such as, document managers, account managers, permission managers, custom control managers, etc.

In your own work you probably have plenty of methods that returns objects, but when is it a Factory Method? The rules are:

  • the method creates a new object
  • the method returns an abstract class or interface
  • the abstract class or interface is implemented by several classes

Factory Method in .NET Core

A search for the word ‘Factory’ in ASP.NET Core and Entity Framework Core results in many hundred instances. Probably half of these are in unit tests, but it goes to show how widespread the use of the Factory pattern is.

An example is the System.Convert class which exposes several static methods that, given an instance of a type, returns another new type. For example, Convert.ToBoolean accepts a string and returns a boolean which value depends on the incoming string value (true or false).

Likewise, the Parse method on many built-in value types (Int32, Double, etc.) is an example of the same pattern.

string myString = "true";
bool myBool = Convert.ToBoolean(myString);

In .NET the Factory Method is typically implemented as a static method that creates an instance of a given type determined at compile time. In other words, these methods don’t return base classes or interface types of which the true type is only known at runtime.

This is exactly where Abstract Factory and Factory Method differ: Abstract Factory methods are virtual or abstract and return abstract classes or interfaces. Factory Methods are abstract and return object types. Two static factory method examples are File.Open and Activator. CreateInstance

public class File
{
 public static FileStream Open(string path, FileMode mode)
 {
 ...
 }
}

And here is Activator.CreateInstance:

public sealed class Activator
{
 public static object CreateInstance(Type type, object[] args)
 {
 ...
 }
}

Conclusion

In conclusion, we see hoe to do the implementation of a factory method in C# Core. The source code of the examples are on GitHub.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.