Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A new and full-featured Injector introspection API (keys, implementations, dependencies, etc.) #29

Closed
gissuebot opened this issue Jul 7, 2014 · 11 comments

Comments

@gissuebot
Copy link

From kevinb9n on February 26, 2007 22:12:58

To support tools, e.g. graph-drawing.  And what about the inverse,
Set<Binding> getDependents(Key) (in Container?)

Original issue: http://code.google.com/p/google-guice/issues/detail?id=29

@gissuebot
Copy link
Author

From crazyboblee on February 26, 2007 20:04:29

Both sound good to me. Should we also have getTrasitiveDependencies()?

Labels: -Type-Defect Type-Enhancement

@gissuebot
Copy link
Author

From kevinb9n on March 01, 2007 22:06:10

changed summary from "Set<Key> Binding.getDependencies()"

Injector.getDependencyGraph() should return a nice DependencyGraph object supporting
the queries/traversals tools would need.  I think there may need to be two types of
edges, one for "depends on" and one for "is provided by"; these two are similar in
some ways but the depends-on relationship is significant for the life of the object.

Summary: Injector.getDependencyGraph()

@gissuebot
Copy link
Author

From kevinb9n on March 12, 2007 18:29:50

(No comment was entered for this change.)

Labels: 1.1

@gissuebot
Copy link
Author

From kevinb9n on March 18, 2007 21:16:05

Slight correction: in the general case the depends-on relationship is significant
for the life of the depending object, but we actually lack the information to know in
what cases the object might only be using the dependency for
construction/initialization and then forgetting about it.  It is possible, though
not necessarily likely, that we want to provide the ability for users to distinguish
between the two types of dependency, so that tools can reason properly about the
dependencies.

The dependency graph seems to have vertices of two types: Keys and Implementations.
A Key is exactly what it is now in the API; an Implementation is the outcome of
performing injection resolution for a Key.  Internally we have several types of
Implementations:

  * those containing a single instance that was created and provided by the Module
using .toInstance()
  * those containing a Provider instance that was created and provided by the Module
using .toProvider(Provider)
  * those containing a Constructor which guice has found to be injectable

None of this has anything whatsoever to do with bindings or @ImplementedBy
annotations.  That information comes into play during injection resolution only and
then is no longer useful in this context.

more later, dinner's here.

@gissuebot
Copy link
Author

From kevinb9n on March 18, 2007 23:18:33

Continuing...

I missed a category.  I think I need to generalize the second bullet, so the complete
list of three would be

  * those referencing a single instance that was created and provided by the Module
using .toInstance()
  * those referencing another Implementation which serves as the provider for this
one (or you could even say the other Implementation can provide the provider for
this one; whooaaah)
  * those containing a Constructor which Guice has found to be injectable

The Implementation object also references a Scope.  For bullet point #1 there can't
be a Scope; it's effectively an automatic singleton as there is no other choice (we
don't clone).

It feels wrong now that our Binding object contains a getProvider() method.
getProvider() does not seem to belong there; it is really this new Implementation
object I am talking about which represents Guice's knowledge of how to Provide
instances for a given Key.

Within an Injector, the "resolves-to" association between Key and Implementation is
many-to-one (1..* to 1).  Every Key can always be uniquely resolved into exactly one
Implementation, but every Implementation has one or more Keys which will resolve to it.

We've also discussed the "provides" association, which is from Implementation to
Implementation and is one-to-many (0..1 to 0..*).  An Implementation might not serve
as the provider for anyone, or it might serve as the provider for several other
Implementations (which conceivably differ only in scope?? puzzled here.); in the
reverse direction, an Implementation might have one unique other Implementation that
serves as its Provider, or none.

Now finally we have the long-awaited "depends on" association!  This is from
Implementation to Key and is many-to-many (0..* to 0..*).

Now all we need to do is define an interface exposing all this information, and then
include the necessary queries and traversals either as additional interface methods
or static utility methods.  Simple!

@gissuebot
Copy link
Author

From kevinb9n on March 19, 2007 01:36:50

Here is some crap.

public interface Implementation<T> {

  enum ProvisionStrategy {
    PRECONSTRUCTED_INSTANCE,
    INJECTABLE_CONSTRUCTOR,
    CUSTOM_PROVIDER,
  }

  ProvisionStrategy getProvisionStrategy();

  // Only the right method for the provision strategy will work; the others
  // will throw IllegalStateException.
  T getPreconstructedInstance();
  Constructor<? extends T> getInjectableConstructor();
  Implementation<? extends Provider<T>> getCustomProviderImplementation();

  Scope getScope();
  Set<Key<? super T>> getKeysThatResolveToThis();
  Set<Dependency<?>> getDependencies();
  Set<Dependency<?>> getDependents();
}

public interface Dependency<T> {
  Implementation<?> getDependent();
  Key<T> getKey();
  Implementation<? extends T> resolveKey();
  boolean isProviderDependency();
}

This is a straw man. pls dissect and discuss.

btw my intention is for issue 11 to be implemented atop this API.  I also think some
of the Binding stuff could perhaps be deprecated.

Summary: A new and full-featured Injector introspection API (keys, implementations, dependencies, etc.)

@gissuebot
Copy link
Author

From kevinb9n on March 19, 2007 01:39:49

Implementation could easily have getProvider() and getInstance() methods.  It is
precisely the "thing" that encompasses the information required to fulfill those.
However, I think this may cause confusion; I'm trying to differentiate the API for
observing the static configuration of an Injector, from the API for using an Injector
to retrieve live application objects (the latter API should continue to be
Injector.java itself).

@gissuebot
Copy link
Author

From kevinb9n on April 29, 2007 11:37:54

too big for 1.1 :(

Labels: -1.1

@gissuebot
Copy link
Author

From kevinb9n on May 31, 2007 14:23:36

I have iterated on the API design a little and have checked it in... I won't say the
revision number but I will just tell you that my newest design is only "half evil".  :)

Bob is insistent that this can be a simple extension of the existing "Binding" API.
I have thought about this a lot and I still do not see how it can.  That API is
useful for working with bindings, but this is something very different.  This is
about keys and fully resolved keys (which the resolver may have had to follow
several bindings to get to, but where it ends up is not the same as a garden-variety
binding).

I'm optimistically re-tagging this for 1.1 because we may have an intern interested
in working on a graphical visualization tool.

Labels: 1.1

@gissuebot
Copy link
Author

From limpbizkit on May 29, 2008 23:51:54

(No comment was entered for this change.)

Labels: -1.1 Milestone-Release2.0

@gissuebot
Copy link
Author

From limpbizkit on August 02, 2008 16:04:35

Done. Elements provides full injector information.

Status: Fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant