17

I understand the concept and can use both the Factory Pattern and Dependency Injection, however they seem a little at odds with each other conceptually. Is it a case of using one over the other? Or can they be used in conjunction with each other?

If using DI would you hard code the creation of classes within a Factory? Wouldn't this defeat the point of DI? As the factory is dependant on the existence of the classes it creates, and thus would need them passed to the factory at runtime when using DI.

Or would you pass the classes that the factory is meant to create to the factory is meant to create? If so wouldn't that defeat the point of building a factory in the first place? As the Injector would basically be doing all the work of the factory.

Thank you very much for your attention, I look forward to your insights.

2 Answers2

10

When you make heavy use of dependency injection, you separate your code into parts with classes/objects holding features & functions, and code where the creating of the former takes place and the dependencies are resolved. The latter can be either done by

  • a DI container
  • Factory classes

So DI is not contrary to the use of Factories, in fact, when you do DI without a DI container you will typically need a lot of factories.

See this blog post for a more complete explanation.

Doc Brown
  • 218,378
9

If using DI would you hard code the creation of classes within a Factory? Wouldn't this defeat the point of DI?

No, it does not violate the Dependency Inversion (not Injection) Principle because it is the purpose of the factory is to create for us some concrete object.

Or would you pass the classes that the factory is meant to create to the factory is meant to create? If so wouldn't that defeat the point of building a factory in the first place? As the Injector would basically be doing all the work of the factory.

You are right!

Factory Patterns are the creation patterns - they are responsible for creating instances.

Dependency Injection patterns are about loose coupling and Dependency Inversion (Inversion of Control) - they inject instances that another instance need to do its job.

They address different problems and can be used in conjunction. An example (maybe not some great but I hope that it would do the job):

class Player {
    string name;
}

interface PlayerFactory {
    Person create();
}

class RealPlayerFactory : PlayerFactory {
    return GetPlayerFromDatabase();
}

class RandomPlayerFactory : PlayerFactory {
    Person result = new Person();
    result.name = GenerateRandomName();
    return result;
}

class Team {
    Team(PlayerFactory playerFactory) {
        for (int i=0; i < 11; ++i) {
            AddPlayer( playerFactory.create() );
        }
    }
}

Use Dependency Injection Patterns to introduce loose coupling.

Use Factory Patterns if you need to delegate the creation of objects.

Pellared
  • 216