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

Lifecycle support in dagger 2 #652

Open
Dunemaster opened this issue Mar 23, 2017 · 8 comments
Open

Lifecycle support in dagger 2 #652

Dunemaster opened this issue Mar 23, 2017 · 8 comments

Comments

@Dunemaster
Copy link

Dunemaster commented Mar 23, 2017

I would like to discuss adding lifecycle support in dagger 2.

If the feature will be recognized useful I will proceed with a pull request.

We have a complex application with several scopes, and often components provide java.lang.Autoclosable/java.io.Closable objects, for example associated with database connections or files.

As for now, we have to track such objects manually and close them.

It would be very convinient and much more reliable to make AutoClosable dagger 2 components, which wold close all required objects when closed themselves.

Here is a raw idea how I would implement it:

  1. Create a new annotation @CloseWithScope for scoped @provides and @BINDS methods
  2. Check that a method marked with @CloseWithScope return an AutoClosable instance
  3. If a module includes a @Binds/@provides method using a @CloseWithScope, than component using this module should be AutoClosable
  4. AutoClosable component should close all @CloseWithScope objects when it is closed
@Dunemaster
Copy link
Author

Dunemaster commented Mar 24, 2017

As for other DI libs, autofac has a similiar mechanics:

http://autofac.readthedocs.io/en/latest/lifetime/disposal.html

And Spring

https://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-lifecycle-disposablebean

@retran
Copy link

retran commented Mar 24, 2017

Unity: https://msdn.microsoft.com/en-us/library/ff660872(v=pandp.20).aspx (HierarchicalLifetimeManager)
Ninject: https://github.com/ninject/ninject/wiki/Object-Scopes

It is very necessary feature.

@Villason
Copy link

Villason commented Oct 9, 2017

I am looking for a similar feature. On top of that, imagine you have many objects depending on the same Closeable resource. Proper closure is not straight forward.

@noclue
Copy link

noclue commented Dec 3, 2017

Support for instance lifecycle events seems quite important. There are objects that refer precious resources i.e. open sockets,background threads. Those need disposal possibly aligned with a particular submodule/scope.

So at minimum I would hope that Component can be declared to extend java.lang. AutoCloseable there by allowing the Component to be closed. Closing the component should propagate to some of the objects within it i.e. AutoCloseable objects that also exhibit other necessary characteristics e.g. belong to particular "closeable" scope or alike.

I realize that such change is a complex one to maintain compatibility with current API etc. This is also important one. Dagger 2 looks immature lacking this simplest of mechanisms. It is also quite ugly (1) to maintain references to closeable objects in some external utility that will externally take care, (2) not be able to leverage Java language syntax for try with resources when working with short lived scopes.

@ronshapiro
Copy link

ronshapiro commented Apr 16, 2019

I think this is a difficult feature to support, and when we had a similar feature (releasable references), it was barely used (only 1 internal usage, and not even correctly).

If I wanted to do something like this, I'd recommend just @Binds @IntoSet Closeable myCloseable(MyCloseable thing); and then close them all in a loop. And then I'd use the SPI to verify that any binding that implements Closeable is scoped and also added to this set.

How does that sound? I'd be happy to help review an extension library to do this.

@facboy
Copy link

facboy commented Sep 23, 2019

@ronshapiro we're using this approach, the main downsides are:

  • a lot of boilerplate @Binds @IntoSet methods (some might view this as a plus given that it's explicit)
  • a bunch of Closeable things that might otherwise have remained uninstantiated become instantiated when somebody invokes the closeables() set. unless i've missed a trick?

@Chang-Eric
Copy link
Member

Leaving this open but marking it as P3. While the @IntoSet solution has the problems mentioned, I think this could still be manually done by having some CloseableManager type that each Closeable injects and registers during provision.

One of the main downsides of supporting something like this is that I think it may add to the confusion about how Dagger works. Especially on Android, I see confusion thinking the component is destroyed when really it is just released and let to be GCed. I worry about people registering Closeable types and then not realizing that if you don't call close() on the component they won't actually get closed.

Also echoing the point before too that there was a releasable scopes feature a while ago that was similar and was used very little while adding a large amount of complexity to Dagger's internals.

@facboy
Copy link

facboy commented Feb 3, 2021

it would be nice if there were a isInitialized() method on Lazy so you could close a Closeable if it had been instantiated, but otherwise ignore it.

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

7 participants