Leo Sutic wrote:
> Stephen McConnell wrote:
> > >It also allows you to specify suppliers (the answer to question 2 is
> > >"yes" for MicroContainer):
> > >
> > > public static Composer getInstance( Supplier supplier )
> > > {
> > > return (Composer) new MicroContainer( ComposerImpl.class )
> > > .component( Supplier.ROLE, supplier ) // Specify supplier of service.
> > > // (The supplier must be another
> proxy.)
> > > .sharedInstance( true ) // Handling policy
> > > .create(); // Create the proxy instance with a
> > > // contained component instance.
> > > }
> > >
> > >I would love to see something similar in Merlin.
> > >
> > Me too! Should this be focussed on Merlin current or Merlin II
> (where Merlin II can
> > be considered more as a general container services > framework)? My
> suggestion
> > would be to trial some things using the containerkit
> ResourceProvider model and sort
> > out what mata info needs to be declared to support the above - for
> example, the
> > sharedInstance is presumable a policy of the implementation class.
> I.e. where
> > information is specific to a component - ensure the possibility for
> the declaration
> > of this at the .xinfo level. Concerning proxies - this is also
> something I would like to see.
>
> Let me explain how MicroContainer handles this now, and how I see
> Merlin handling it:
>
> First, what you see here is basically the instantiation of a
> MicroContainer *factory*. It is not until the create() method is
> called at the very end that the actual MicroContainer is created and
> returned.
>
> new MicroContainer( ComposerImpl.class )
> .component( Supplier.ROLE, supplier )
> .sharedInstance( true )
> .create()
>
> Another way of writing it would be:
>
> MicroContainer mc = new MicroContainer( ComposerImpl.class ); // 1
> mc.addComponent (Supplier.ROLE, supplier); // 2
> mc.setSharedInstance (true); // 3
>
> Composer myComponent = (Composer) mc.create(); // 4
>
> And bang, myComponent holds a reference to a proxy containing one
> instance of ComposerImpl.
Yep.
Basically following the factory model mentioned earlier my Pete and Nicols.
>
> How to integrate this with .xinfo-level metainfo? Well, I've numbered
> the steps above:
>
> *** First, assume that all service instances are SINGLETON (as I
> understand Merlin, Singleton handling policy is equivalent to
> ThreadSafe in ExcaliburCM) We can handle TRANSIENT and POOLED as well,
> but for now leave that. ***
Correct, and Yes - I agree with the approach.
>
>
> 1. At this point all we know is the component's implementing class.
> That's enough to grab the associated .xinfo, if any. So we grab it and
> store it.
>
> 2. Here the user provides a supplier for a role. Store that role->impl
> mapping.
Ummm - problem - who is the user ? In Merlin and the Assembly related
stuff, I can see a declaration of a factory and I can see an xinfo with
declaration of dependecies, and I can see either (a) Merlin/Assembly
figuring out the suppier automatically, or (b) the "assembler" including
directives in an application profile to override any default solutions.
In this case, the oligation is on the component xinfo to declare the
service dependecies, and (b) for the assembly to either run with the
defaults or decalre an explicit assembly directive.
>
> 3. User overrides handling policy.
>
> 4. At this point we have (a) .xinfo description providing defaults (b)
> user overrides. Merge those.
Lets say "resolve" those (the word *merge* has implications) :-)
> For dependencies this means that for every dependency in the xinfo not
> satisfied by the user via overrides, consult the service registry.
There are two distinct things here:
(a) an explicit profile that an assembler declares in an assembly profile
(b) an assembly directive - e.g. use A to service B
In the Assembly package - the phrase "consult the registry" means get
the solution and take the explicit declaration if one is available - and
notions of explicitly wiring A to B are not presently addressed (but
desirable).
> If the handler policy has not been set, use whatever is in xinfo,
Can you expand just a bit on what your meaning by the "handler". Is
this the factory ?
> and if there is no xinfo, well... do something reasonable.
Yep - not currently available but needs to be done.
> End result: A full environment for the target component. If possible,
> create a proxy around the target component that holds the
> ComponentManager etc. for the component and that exposes all the
> target component's interfaces. Return that.
Yep.
>
> What I'm still trying to figure out is just how the ServiceRegistry
> works. Does it "learn"? When I create a new instance of a Foo
> component, will the registry capture the creation parameters and use
> it to satisfy future requests for a Foo component?
Nothing terribly inteligent - the registry (in Merlin) captures the
complete profile of the creation criteria (configuration and context).
This information consitutes a profile that is re-used for any service
demand for a componet of the same type. This solves 100% of my
requirements but is non-optimal - the work in Merlin II (the Excalibur
Assembly stuff) is nuch more structured in this respect - the service
registy has explicit knowlege of multiple profiles for a given type.
Each profile holds configuration, context and parameers instantiation
criteria - a unique instantiation profile. So - the answer to the
question is Yes - but the Merlin II apprach is much more solid.
>
>
> Now on to how to handle TRANSIENT services:
>
> The problem with transient services is that you can not give the same
> instance to two composers. This ceases to be a problem with proxie'd
> services, as you can stuff all creation parameters into the proxy and
> then let the proxy create a new component instance every time it is
> needed. A clone() method on steriods, in short. What appears as a
> component is actually a proxy that can work as a factory when needed.
>
> So suppose we have an instance of component A that is TRANSIENT. We
> have two components with dependencies on A: B and C.
>
> We can not give our only instance of A to both B and C.
>
> Solution: When overriding the role->component mapping for B and C
> (that is, we say "when satisfying B and C's dependency on A, use this
> component"), A's clone() method is called, and B and C receives a
> clone each of A. THis cal always be done, if the clone method is
> implemented so that it only actually performs a cloning if the
> handling policy is TRANSIENT.
In Merlin this is doen inside the compoent manager - as far as
dependecies are concerned the compoent types are arranged and supplied
to the manager. The manage invokes instantation of a new component or
returns a singleton componet based on the implementation policy.
Basically the same idea as you talking about.
>
>
> (This, BTW, is why the "supplier" in my MicroContainer example must be
> a MicroContainer: It guarantees cloneability:
>
> .component( Supplier.ROLE, supplier ) // Specify supplier of service.
> // The supplier must be another proxy.
>
> )
Not sure I'm following the last point - my assumption is that
MicroContaienr could be renamed to DefaultFactory and that because your
always dealing with a factory model, then you can deal with the
lifestyle policies in a reasonably consitent way. My assumption is that
there are basically two types of component sources (a) componet classes
that act as a factory via class.newInstance(), and (b) explicit
factories along the lines your describing. I'm reasonably confident
that the two approaches cover the entire spectrum of usage cases that we
will need to deal with.
Cheers, Steve.
--
Stephen J. McConnell
OSM SARL
digital products for a global economy
mailto:[EMAIL PROTECTED]
http://www.osm.net
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>