BBauer42
BBauer42

Reputation: 3667

Inject factory and let it perform creation, or inject everything?

Is it good practice to inject a factory, then perform instantiation of many objects inside a constructor?

private readonly SafeClient<AccountProxy, IAccountService> _accountProxy;
private readonly SafeClient<AccountClassProxy, IAccountClassService> _accountClassProxy;
private readonly SafeClient<CarrierProxy, ICarrierService> _carrierProxy;
private readonly SafeClient<TransportationTypeProxy, ITransportationTypeService> _transportationTypeProxy;

public AccountController(ISafeClientFactory clientFactory)
{
    clientFactory.UserName = "user";
    clientFactory.Password = "password";
    _accountProxy = clientFactory.CreateClient<AccountProxy, IAccountService>();
    _accountClassProxy = clientFactory.CreateClient<AccountClassProxy, IAccountClassService>();
    _carrierProxy = clientFactory.CreateClient<CarrierProxy, ICarrierService>();
    _transportationTypeProxy = clientFactory.CreateClient<TransportationTypeProxy, ITransportationTypeService>();
}

Or is it better to just inject everything? What are the pros and cons? Sorry, I'm new to this whole DI thing. Thanks.

public AccountController(
    ISafeClient<IAccountService> accountProxy,
    ISafeClient<IAccountClassService> accountClassService,
    ISafeClient<ICarrierService> carrierService,
    ISafeClient<ITransportationTypeService> transportService) 
{
     //assignment here
}

Upvotes: 3

Views: 83

Answers (2)

Steven
Steven

Reputation: 172776

By injecting a factory into the constructor, you are hiding the real dependencies and has about the same downsides as you get with the Service Locator anti-pattern. These downsides include:

  • it hides a class' dependencies, causing run-time errors instead of compile-time errors
  • it makes the code more difficult to maintain because it becomes unclear when you would be introducing a breaking change
  • it makes it much harder for the consumer of the component to see whether the component might have a Captive Dependency and it makes tools blind; they will not be able to spot those errors.
  • Might hide the fact that a class uses too many dependencies. In other words it hides the fact that the class might violate the Single Responsibility Principle.

You would typically use a factory to delay building of part of your object graph, but in case you call the factory inside the constructor, you don't delay the construction at all. You get no extra benefits, only downsides.

So it is absolutely better to inject dependencies directly.

Upvotes: 4

Johann Gerell
Johann Gerell

Reputation: 25591

I usually go with the second example, and this is the rationale I live by:

If a dependency B of A can be instantiated at construction time for A, then it should be instantiated outside of A and constructor injected into A. If there's not enough information to instantiate B at construction time for A, then inject a factory that can instantiate B when enough information exists.

Upvotes: 4

Related Questions