Leo Simons wrote:

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.

I don't recall any major hell. I do recall proposed it, writing it, committed it, and initiated the vote - but at the end of the day i9s was a no-brainer. A choice between avalon lock-in and liberty.


Let's just clear the tech side of things up a little.

OK - I'm focusing!

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. */

Isn;t this a question of separation of concerns? No really - I know your going to thing this is one of those auto response replies .. but shit .. this look like one way overloaded interface.


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();
  }
}


OK

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+?

Will run in Merlin 3.3 and 3.4 because it implements a null constructor therefor logic falls back to classics.


* is not "avalon-framework 4.2 compatible"

Is avalon 4.1 and 4.2 compatible because it declares a null constructor.

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.

The is not issue re. backward compatibility providing your component implements a null constructor and implements classic avalon interfaces concerning phased supply of artifacts. Yes - there is an no backward compatibility for new components that leverage the constructor model.


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.

I disagree.

You going to have to explain this one.

I don't see how you can get compile time checking or memory reduction without final variables linked to constructor injection of artifacts. I also doubt the lines of code reduction benefit can be achieved to the same level through another approach relative to the underlying JVM. As to elimination of author errors - yes - in principal one could write another compiler but does that make sense?

Cheer, Steve.

cheers,

- Leo

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




--

|---------------------------------------|
| Magic by Merlin                       |
| Production by Avalon                  |
|                                       |
| http://avalon.apache.org              |
|---------------------------------------|

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



Reply via email to