Stephen McConnell wrote:
This is no different to the introduction of the Serviceable interface and ServiceManager.

I would argue the situation is a bit different now from then, but yes, its very comparable. I would also argue that we managed that introduction rather badly and it was a major hell to get right.


Let's just clear the tech side of things up a little. Here's an example component to consider...

interface A { void doStuff(); }

/** Use /either/ setter injection, constructor injection or the
    avalon contract. Combining them results in a problem (perhaps
    because connection to a database is initialized twice...),
    in this case simulated by throwing an exception. */
class AImpl implements A, Serviceable, MyDependencyAware, BAware
{
  MyDependency dep;
  B b;
  boolean injected = false;

  // avalon 4.1, webwork 2
  public AImpl() {}

  // pico 1.0, avalon 4.2?
  public AImpl( MyDependency dep, B b )
  {
    this.dep = dep;
    this.b = b;

    injected();
  }

  // avalon 4.1, avalon 4.2?
  public void service( ServiceManager sm )
  {
    this.dep = (MyDependency)sm.lookup( MyDependency.class );
    this.b = (B)sm.lookup( B.class );

    injected();
  }

  // webwork2, avalon 4.3???
  public void setDep( MyDependency dep )
  {
    this.dep = dep;
  }

  // webwork2, avalon 4.3???
  public void setB( B b )
  {
    this.b = b;
  }

  // webwork2
  public void initComplete()
  {
    injected();
  }

  private void injected()
  {
    if( injected )
      throw new ShouldNotInjectDependenciesTwiceException();
    injected = true;

    if( dep == null )
      throw new NullArgumentException( "dep" );
    if( b == null )
      throw new NullArgumentException( "b" );
  }

  private void checkInjected()
  {
    if( !injected )
      throw new DependencyInjectionHasNotBeenCompletedException();
  }

  public void doStuff()
  {
    checkInjected();
  }
}

IIUC, This component...
  * runs in phoenix 3.0a+
  * runs in ECM 1.0+
  * runs in Webwork 2.0+
  * runs in PicoContainer 1.0+

  * is "avalon-framework 4.1.4 compatible"

This component....
  * might not run in Merlin 3.3+?
  * is not "avalon-framework 4.2 compatible"

there was no such issue with the Serviceable change. No way you could have implemented the Serviceable interface prior to it existing. Dependency injection is a more complex contract than the interface-based avalon-framework contracts, hence managing change to it (or introducing it) is also more involved.

I don't have a big issue with this example breaking in merlin. I can totally understand the need to innovate and how certain changes may make sense in merlin. I simply don't know merlin well enough to make a judgement call. I do, however, know avalon-framework and these kinds of issues well enough to know there's an issue here.

It effectively destroys the common denominator between these projects for no good reason.

The good reasons:

  1. improved compile time checking
  2. reduced memory consumption
  3. significant reduction of lines of code
  4. elimination of potential errors by component
     authors related to sequential artifact delivery
  5. reduced dependency on framework interfaces

those are Good Things. But you could get all that in a different manner without causing any of the issues like the example highlighted above.


cheers,

- Leo

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to