The Factory Pattern In .NET Core

Similar to the Singleton and Mediator Patterns, the Factory Pattern is part of the “Gang Of Four” design patterns that basically became the bible of patterns in OOP Programming.

The Factory Pattern is a type of “Creational Pattern” that deals with the problem of creating an object when you aren’t quite sure on the “requirements” to create said object. That’s probably a little bit of a confusing way to explain it. But in general, think of it like a class that’s sole purpose when called, is to create an object and return it to you and you don’t need to know “how” the creation of that object actually happens.

The Factory Pattern In C#

Let’s drive right in. First, let’s look at a plain C# example in code :

public interface IVehicle
{
    VehicleType VehicleType { get; }
    int WheelCount { get; }
}

public class Car : IVehicle
{
    public VehicleType VehicleType => VehicleType.Car;
    public int WheelCount => 4;
}

public class Motorbike : IVehicle
{
    public VehicleType VehicleType => VehicleType.Motorbike;
    public int WheelCount => 2;
}

public enum VehicleType
{
    Car, 
    Motorbike
}

class VehicleFactory
{
    public IVehicle Create(VehicleType vehicleType)
    {
        switch(vehicleType)
        {
            case VehicleType.Car:
                return new Car();
            case VehicleType.Motorbike:
                return new Motorbike();
            default:
                throw new NotImplementedException();
        }
    }
}

Let’s walk through bit by bit.

First, we have an interface called IVehicle which is implemented by both the Car and Motorbike classes. We also have a vehicle enum type which we later use in our factory.

Next comes our actual factory. This has a single method called “Create” on it. I personally prefer my factories to only ever have a single method called “Create” just to keep them simple. It takes in a vehicle type and spits out an instance of a vehicle.

Now the point here is that the caller to the factory doesn’t need to know “how” we are creating these objects, just that it can call them and it will get back the “right” one. It doesn’t need to know that it can simply call “new Car()” to get a car, maybe the creation of a car is actually more complex than that, but it let’s the factory work it out. Let’s illustrate that further…

Illustrating The Abstraction

Let’s take our above example and imagine we add another vehicle type. But it’s a complex one. Infact, we are adding a “Quad Bike”.

public enum VehicleType
{
    Car, 
    Motorbike, 
    QuadBike
}

Now we actually want our QuadBike to still return a MotorBike object, just with a few changes. For that, we change our Motorbike object to the following :

public class Motorbike : IVehicle
{
    public Motorbike(bool isQuadBike)
    {
        VehicleType = isQuadBike ? VehicleType.QuadBike : VehicleType.Motorbike;
        WheelCount = isQuadBike ? 4 : 2;
    }

    public VehicleType VehicleType { get; private set; }
    public int WheelCount {get; private set;}
}

Now imagine if everyone who was already creating motorbikes now needed to change their creation to pass in false. But with our handy factory…

class VehicleFactory
{
    public IVehicle Create(VehicleType vehicleType)
    {
        switch(vehicleType)
        {
            case VehicleType.Car:
                return new Car();
            case VehicleType.Motorbike:
                return new Motorbike(false);
            case VehicleType.QuadBike:
                return new Motorbike(true);
            default:
                throw new NotImplementedException();
        }
    }
}

So we’ve actually completely changed how the creation of an object happens, but because it’s abstracted away behind a factory, we don’t need to worry about any of it (Well… except to change the factory itself). That’s essentially the factory in a nutshell. Let’s look at how .NET Core makes use of this pattern in a different way.

Factories In The .NET Core Service Collection

You may be here because you’ve seen the intellisense for “implementationFactory” popup when using .NET Core’s inbuilt dependency injection :

So in this context what does factory mean? Actually… The exact same thing as above.

Let’s say I have a service that has a simple constructor that takes one parameter. This is pretty common when you are using a third party library and don’t have much control over modifying a constructor to your specific needs.  Let’s say the service looks like so :

public class MyService
{
    public MyService(bool constructorParam)
    {

    }
}

If we bound this service in our service collection like so :

services.AddTransient<MyService, MyService>();

That’s not gonna fly. The only constructor available has a boolean parameter, and there are no parameterless constructors to use. So we have two options, we can use some janky injection for the boolean value or we can create a factory to wrap the constructor.

Similar to the above, we can actually create a real factory that has a Create method that returns our object :

public static class MyServiceFactory
{
    public static MyService Create(IServiceProvider serviceProvider)
    {
        return new MyService(true);
    }
}

And we bind it like so :

services.AddTransient<MyService>(MyServiceFactory.Create);

Now whenever MyService is requested, our factory method will run. If creating a full on factory is a bit much, you can just create the Func on the fly in your AddTransient call :

services.AddTransient<MyService>((serviceProvider) => new MyService(true));

The use case for a “factory” here can be a little different because you might have an actual need to constantly create the object using a custom method at runtime and that’s why you are binding a custom method to create your object, compared to the “pattern” of abstracting away your constructor, but both can be called the “Factory Pattern”.

When Should I Use The Factory Pattern?

Dependency Injection/Inversion has at times taken the wind out of the sails of the factory pattern. Loading up a constructor with dependencies isn’t such a big deal because the caller is typically depending on an interface, and dependency injection is taking care of the rest.

However, I do typically end up using a factory when the creation of an object is dependent on runtime variables/state and I want to contain this logic in a parameter. Aslong as you know what the factory pattern is and don’t try and “force” it anywhere it shouldn’t be, you will find it comes in useful a couple of times in ever .NET project.

ENJOY THIS POST?
Join over 3.000 subscribers who are receiving our weekly post digest, a roundup of this weeks blog posts.
We hate spam. Your email address will not be sold or shared with anyone else.

2 comments

  1. I have been searching for a good example of a creational design pattern using DI and this article comes close.
    In my case, I need to use a config value to determine which concrete implementation will be used and am attempting to figure out the DI container aspect in .net core 3.1. My questions below are in reference to that.

    Your example uses IServiceProvider in your factory class. What does that interface look like? Does dependency injection need to be done on the IServiceProvider interface? If so, is there a concrete implementation?

    1. Reading back through this it doesn’t explain it great.

      IServiceProvider is actually the .NET Core ServiceCollection. When you call it like I have, you can actually use the IServiceProvider to get any dependencies you would like to resolve. So for example reading your question, you could have :

      public static class MyServiceFactory
      {
      	public static IMyService Create(IServiceProvider serviceProvider)
      	{
      		if(checkMyConfig == true)
      		{
      			return serviceProvider.Get<FirstService>();
      		}else 
      		{
      			return serviceProvider.Get<SecondService>();
      		}
      	}
      }
      

      So you can use logic to determine which class to return, but you can still use DI to resolve that class.

      IServiceProvider is inbuilt to the .NET Core DI system (https://docs.microsoft.com/en-us/dotnet/api/system.iserviceprovider.getservice?view=netcore-3.1). It’s automatically wired up etc.

Leave a Reply

Your email address will not be published. Required fields are marked *