question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature Request: component introspection based on a base class/interface

See original GitHub issue

I’m working on setting up the graph architecture in my application (Twitter for Android), and I ran into the problem of cleaning up scoped bindings when a Dagger component is discarded.

Let’s say that I inject a user database from a scoped Dagger component. Dagger takes care of creating an instance of my database when first requested, and injecting it to all clients of the dependency. No one client owns the database object itself, so the responsibility of closing it when discarding the component is not clearly assigned. Extracting from the component all references that require cleanup, however, poses several issues:

  • Exposing all bindings that require cleanup through provision methods in the component is undesirable, since it forces me to publish bindings that should remain private. Also, it’s error-prone, since it requires me to write the cleanup code to call each method explicitly.
  • Getting an object for cleanup would create it if it was uninitialized.

I have addressed the first issue by providing objects that require cleanup to a multibound set, and putting a bunch of lint rules in place to detect omissions. This works, but it’s clunky and verbose. I don’t have a good solution for the second problem.

Taking a step back, it seems to me that this is a particular case of the larger problem of extracting objects from a component based on properties like base classes or implemented interfaces. Ideally, I would like to be able to declare such a multibinding as this:

@Multibindings
interface MyMultibindings {
    @NotNull
    @InstancesOf(type = Closeable.class, transitive = false, onlyIfInitialized = true)
    Set<Closeable> closeables();
}

I threw in a couple of flags that would make this feature more generally useful:

  • transitive, for configuring whether the multibinding should include nesting scopes.
  • onlyIfInitialized, to select all providers or only those in the initialized state.

Incidentally, this would be particularly useful if Dagger’s scoped providers would expose the functionality to query and update their state, since that may be used to release providers on demand while doing the proper cleanup (which doesn’t seem to be available in the Releasable References API).

Would this make sense in the overall design of Dagger? Do you have an alternative solution for this kind of problem?

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:1
  • Comments:8

github_iconTop GitHub Comments

1reaction
ronshapirocommented, Dec 9, 2016

Firstly, we’re working on an API to make it easier to your own additional static analysis on the graph. Hopefully that’ll help to make sure people don’t slip up (and that your checks are accurate).

We’re discussing the idea of providing features for closing resources within Dagger. To help me understand: do you want to group bindings that you want closed all at once, or do you want this at the individual binding level?

There are definitely some manual ways of doing this:

@Provides @ActivityScope @Task1
Closer provideCloser() { return new com.google.common.io.Closer(); }

@Provides @ActivityScope @Task2
Closer provideCloser() { return new com.google.common.io.Closer(); }

@Provides
Database provideDb(@Task1 Closer closer) {
  return closer.register(new Database());
}

Is that similar to what you were thinking about?

0reactions
cesar1000commented, Mar 11, 2019

Closing since, in hindsight, injecting Closer or similar event notifier explicitly does sound like a better option.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Wildcard multibindings for generic classes · Issue #385 - GitHub
Feature Request : component introspection based on a base ... can write a code generator to simplify it, but this isn't a feature...
Read more >
Java Generics Example Tutorial - Generic Method, Class ...
Generics in Java with collection classes is very easy but it provides a lot more features than just creating the type of collection....
Read more >
How we handle feature requests - Artlogic Support
Following our internal feature request meetings, viable requests are selected and then ... This schedule is then mapped out based on a number...
Read more >
PhishER: Feature Requests - Knowledge Base - KnowBe4
Feature Request - An option to mass retry queries, or to delete them from the query list. Sanat Varasada; 4 months ago. 1...
Read more >
Create new main component from existing component
Create new main component from existing component. ◇ Overview After releasing "State" feature, it's been able to prepare complex interactions ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found