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

Support Assisted Injection via Factory Codegen #467

Merged
merged 40 commits into from
Jan 24, 2024
Merged

Conversation

SentryMan
Copy link
Collaborator

@SentryMan SentryMan commented Dec 3, 2023

  • when a bean is annotated with @AssistFactory a factory class is generated which will handle all managed injections while accepting user dependencies
  • supports constructor, field, and method assisted injection

Note the example below has been edited to reflect the built behaviour.

Given a factory interface with a single method:

public interface CssFactory {

  Scanner scanner(String path);
}

A class with @AssistFactory(CssFactory.class):

@AssistFactory(CssFactory.class)
class CssScanner implements Scanner {

  private final Path path;
  private final MyInjectedComponent myComponent;

  CssScanner(@Assisted Path path, MyInjectedComponent myComponent) {
    this.path = path;
    this.myComponent = myComponent;
  }

  @Override
  public String scan() {
    return "scanWith|path=" + path + " | myComponent =" + myComponent.hi();
  }
}

An assist factory class will be generated. (Naturally, it too will be processed and have a DI class created)

@Generated("io.avaje.inject.generator")
@Named("css")
@Component
final class CssScanner$AssistFactory implements CssFactory {

  private final MyInjectedComponent myComponent;

  CssScanner$AssistFactory(MyInjectedComponent myComponent) {
    this.myComponent = myComponent;
  }

  /**
   * Fabricates a new CssScanner.
   */
  @Override
  public CssScanner scanner(Path path) {
    var bean = new CssScanner(path, myComponent);
    return bean;
  }
}

Then the CssFactory can be used like:.

@Component
public class CssThing {

  private final CssFactory factory;

  CssThing(CssFactory factory) {
    this.factory = factory;
  }

  public String scan(Path path) {
    Scanner scanner = factory.scanner(path);
    return scanner.scan();
  }
}

will resolve #466

@SentryMan SentryMan self-assigned this Dec 3, 2023
@SentryMan
Copy link
Collaborator Author

Hmm, I can do better

@SentryMan SentryMan marked this pull request as draft December 3, 2023 19:09
@SentryMan SentryMan marked this pull request as ready for review December 3, 2023 21:38
@SentryMan SentryMan changed the title Support @Assisted Support Assisted Injection via Factory Codegen Dec 3, 2023
@rbygrave
Copy link
Contributor

Adding tests. Noting that when there is no target factory the generated AssistedFactory can't be injected into other components (with compilation error I believe because it does not exist in the first compilation round).

Thinking that we should make the target factory required at this stage - that feels like the correct thing to do at this stage. Later on if there is demand for not having a target factory interface then that can be revisited / looked at again.

Fix qualifier determination, was ignoring qualifier annotations
@SentryMan
Copy link
Collaborator Author

it does not exist in the first compilation round

hmm, this highlights another potential problem in that inject doesn't know how to handle beans that directly use generated code.

@SentryMan SentryMan added the enhancement New feature or request label Jan 24, 2024
@rbygrave rbygrave self-requested a review January 24, 2024 19:19
@rbygrave rbygrave merged commit dbcc971 into avaje:master Jan 24, 2024
4 checks passed
@rbygrave rbygrave added this to the 9.11 milestone Jan 24, 2024
@SentryMan SentryMan deleted the assist branch January 24, 2024 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

hope to support @Assisted... Annotation
2 participants