My previous post led to this comment by Phil Haack:
Your LazyOrderShipper directly instantiates an OrderShipper. What about the dependencies that OrderShipper might require? What if those dependencies are costly?
I didn't want to make my original example more complex than necessary to get the point across, so I admit that I made it a bit simpler than I might have liked. However, the issue is easily solved by enabling DI for the LazyOrderShipper itself.
As always, when the dependency's lifetime may be shorter than the consumer, the solution is to inject (via the constructor!) an Abstract Factory, as this modification of LazyOrderShipper shows:
public class LazyOrderShipper2 : IOrderShipper
{
private readonly IOrderShipperFactory factory;
private IOrderShipper shipper;
public LazyOrderShipper2(IOrderShipperFactory factory)
if (factory == null)
throw new ArgumentNullException("factory");
}
this.factory = factory;
#region IOrderShipper Members
public void Ship(Order order)
if (this.shipper == null)
this.shipper = this.factory.Create();
this.shipper.Ship(order);
#endregion
But, doesn't that reintroduce the OrderShipperFactory that I earlier claimed was a bad design?
No, it doesn't, because this IOrderShipperFactory doesn't rely on static configuration. The other point is that while we do have an IOrderShipperFactory, the original design of OrderProcessor is unchanged (and thus blissfully unaware of the existence of this Abstract Factory).
The lifetime of the various dependencies is completely decoupled from the components themselves, and this is as it should be with DI.
This version of LazyOrderShipper is more reusable because it doesn't rely on any particular implementation of OrderShipper – it can Lazily create any IOrderShipper.
Remember Me
a@href@title, b, em, i, strike, strong
Page rendered at Saturday, February 04, 2012 8:31:46 PM (Romance Standard Time, UTC+01:00)
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.