Does factory design pattern violate Dependency Inversion Principle of solid principle in C#?

110 Views Asked by At

By definition, dependency injection promotes loosely coupled, maintainable, and testable code, and using interface and constructor injection we can get the object of the class implementing the interface.

But when we implement factory we create the object based on the passed Type in the factory method Eg:

interface IVehicle
{
    int WheelCount();
}

class car : IVehicle
{
    int WheelCount() 
    { }
}

class bike : IVehicle
{
    int WheelCount()
    { }
}

class factory
{
    public IVehicle factoryMethod(string type)
    {
        switch(type)
        {
            case "bike":
                new bike();
                break;

            case "car":
                new car();
                break;
        }
    }
}

in main():

factory obj = new factory();
IVehicle vehicle = obj.factoryMethod("bike");

As we are creating the object by directly instantiating the concrete classes within the factory method.

So does the factory design pattern violate Dependency Inversion Principle?

2

There are 2 best solutions below

2
kevalsing On

No, it doesnt.But the way your code is written does violate.

Instead, if you simply modify yur code for Factory class a little, it will adhere to DI principle.

Like this :

Class Factory{

 private IVehicle bikeInstance;
private IVehicle carInstance;

public Factory(IVehicle bike, IVehicle car)
{
    bikeInstance = bike;
    carInstance = car;
}

}

Inject the instances through Factory class constructor and return them through faxctoryMethod()

5
steven01804 On

The factory know the type, but the dependency injected class does not.

public interface IEngine
{
    void Start();
    void Stop();
}
public class DieselEngine : IEngine
{
    public void Start() { Console.WriteLine("Diesel engine started"); }
    public void Stop() { Console.WriteLine("Diesel engine stopped"); }
}
public class GasEngine : IEngine
{
    public void Start() { Console.WriteLine("Gas engine started"); }
    public void Stop() { Console.WriteLine("Gas engine stopped"); }
}
public static class EngineFactory
{
    public static IEngine CreateEngine(string type)
    {
        switch (type)
        {
            case "diesel":
                return new DieselEngine();
            case "gas":
                return new GasEngine();
            default:
                throw new ArgumentException("Invalid engine type");
        }
    }
}

class Car
{
    private IEngine engine;
    public Car(IEngine engine)
    {
        this.engine = engine;
    }
    public void Start()
    {
        engine.Start();
    }
    public void Stop()
    {
        engine.Stop();
    }
}

In this example we have a factory that creates different engines based on the passed in type. But to the dependency injected class car, that does not matter as we are injecting IEngine and not any specific type.

In the main a car could be created like this

Car car = new(EngineFactory.CreateEngine("diesel"));
car.Start();
car.Stop();