Any place where you need a run-time value to construct a particular dependency, Abstract Factory is the solution.
I would argue against this. Dependencies should not be constructed using runtime data, as explained here. In summary the article states:
Don’t inject runtime data into application components during construction; it causes ambiguity, complicates the composition root with an extra responsibility and makes it extraordinarily hard to verify the correctness of your DI configuration. Instead, let runtime data flow through the method calls of constructed object graphs.
When we let runtime data “flow through the method calls of constructed object graphs” instead, you’ll see the usefulness of Abstract Factories decline. They might still be used when runtime data is used to choose from multiple dependencies (compared to injecting runtime data into a dependency), but even then Abstract Factories are typically not the best solution, as explained here. In summary the article states:
Generally, the use of a factory abstraction is not a design that considers its consumers. According to the Dependency Injection Principle (DIP), abstractions should be defined by their clients, and since a factory increases the number of dependencies a client is forced to depend upon, the abstraction is clearly not created in favor of the client and we can therefore consider this to be in violation of the DIP.
Instead, patterns such as Facade, Composite, Mediator and Proxy are generally a better solution.
That doesn’t mean you can’t have code in your application that produces dependencies, but it should not be defined as abstraction that is used by other application components. Instead, factory-like behavior should be encapsulated into adapters that are defined as part of your Composition Root.
When you only have these factory-like logic and dependencies as part of your Composition Root, it doesn’t really matter whether you define an IRepositoryFactory
or merely use an Func<IRepository>
to construct such dependency, since the IRepositoryFactory
would be defined in the Composition Root as well (since the application has no business in using such factory).
That said, in the rare case that an Abstract Factory is the right abstraction (which will typically happen when you are building a reusable framework), I do find the use of factory interfaces much more intend revealing than the use of delegates. It is a bit more verbose, but much clearer what the meaning is of such a thing. An IControllerFactory
is more intend revealing than Func<IController>
.
I would say this even more holds for factories that do not produce dependencies but data values instead. Take for instance the example of injecting a Func<DateTime>
into a constructor. What does this actually mean and what value does it return? Is it intuitive that it returns a DateTime.Now
, or does it return DateTime.Today
, or something else? In that case it would be much clearer to define an ITimeProvider
interface with a GetCurrentTime()
method.
NOTE: This answer was updated on July 2017 to reflect my latest views.