0

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?

3
  • Abstract factories are often a DIP violation, but not for the reason you think. This blog post, which I wrote seven years ago, goes into more details. Commented Nov 13, 2023 at 12:48
  • That said, when the consumer takes a dependency on the concrete factory class, it will cause indirect coupling between the consumer and the vehicle implementations. This will also force bike and car to live in a referenced assembly. If, on the other hand, the factory is hidden behind an abstraction, it allows you to move both the factory and the vehicle implementations to an unreferenced assembly, which could even be loaded dynamically as a plugin. In that case the consumer is decoupled from the implementations, even though it uses a "car" key. The implementation can still be changed. Commented Nov 14, 2023 at 12:09
  • Mark Seemann and I actually have an extensive discussion about the factory pattern with its different variations (including the one you present in your question) in section 6.2 of our book DIPP&P. Commented Nov 14, 2023 at 12:12

2 Answers 2

1

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(); 
Sign up to request clarification or add additional context in comments.

5 Comments

'New is Glue' they say. using new keyword is a tight coupling, as a generale rule. Object creation should be left to DI container. Look at my code and share your inputs/comments. I would like to hear your thoughts.
I used the new keyword for brevity, not an actual recommendation
if my understanding is correct then you are implying that we encapsulate the creation of an object in the factory method and move the creation out of the place where it will be used. Hence it's not violating the Dependency Inversion Principle of solid, as factory method is not using it.. its just creating it.
Right the factory is only concerned with creating the various objects, and it returns it as the abstraction not as a concrete class. Outside the factory the exact class type doesn't matter, only that the object returned has the methods or properties defined by the interface.
@steven01804, dependencies are transitive. By making EngineFactory static, you not only cause tight coupling between EngineFactory and its consumer, but also between the consumer and the dependencies of EngineFactory. In your example, this isn't a big problem, because it is the applicationsMain that calls EngineFactory. But this is easily overlooked by developers reading this. This is a problem because once the Car class starts to depend on the static EngineFactory, it also starts to depend (transitively) on DieselEngine and GasEngine.
-1

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()

2 Comments

a factory that just passes objects around? Seems like this isn't a factory anymore, but just some kind of instance-cache. Now you may apply to DI; but definitly not more to factory-pattern, whose concern is to create objects.
it looks like more of a constructor injection of DI than of a Factory pattern

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.