Lifecycles
A lifecycle in dconstructor controls how long a particular instance of a class will be kept around. The canonical examples of this are SingletonLifecycle? and InstanceLifecycle?, but you can create your own.
SingletonLifecycle? indicates that a particular object will never expire. InstanceLifecycle? indicates that an object expires as soon as it is created.
Using Your Lifecycle
When you register a type with your builder, you can specify the lifecycle:
auto crazy = builder.get!(MyCrazyLifecycle); builder.bind!(MyClass, MyInterface)(crazy); builder.register!(SomeOtherClass)(crazy);
Most of the time, you'll be using one lifecycle for most of your classes and a different lifecycle for a few. To specify which lifecycle should be used by default for all newly-registered types, set builder.defaultLifecycle.
Additionally, there is a way to specify one of the default lifecycles: a singleton can implement the interface Singleton, and a class that should be rebuilt each time can implement the interface Instance. These are defined in dconstructor.property.
Creating Lifecycles
A lifecycle must implement dconstructor.lifecycle.ILifecycle. Whenever an object with the given lifecycle is built, dconstructor queries that lifecycle for its current key. On subsequent requests for the object, dconstructor will ask the lifecycle if that key is current.
Example: Per Web Request Lifecycle
Let's use an example using an HTTP server. You want your objects to last for only one web request unless you specify otherwise.
The core of a Lifecycle is pretty simple -- it's a wrapper around a ulong. The simplest way of implementing this is to subclass dconstructor.lifecycle.Lifecycle and call the "advance()" method every time a new HTTP request is processed:
class PerWebRequest : Lifecycle { this () { // the exact implementation depends on your Http libraries HttpContext.addOnRequestProcessingStarted({ this.advance(); }); } }
To use this, you can set Builder.defaultLifecycle to an instance of PerWebRequest?.
Time-based lifecycles
What if your objects only last a certain amount of time? Whenever they're built, they expire ten seconds later. (No, I don't have a use case for this.)
Here, you want to implement ILifecycle directly. The key for the current lifecycle should be the current time (in milliseconds or ticks or whatever resolution you need):
override ulong key() { return tango.time.Clock.Clock.now.ticks; }
When checking whether a key is current, you can compare it to the current time:
override bool current(ulong key) { auto time = Time.fromTicks(key); return (Clock.now - time).seconds < 10; }
Putting it all together:
import tango.time.Clock, tango.time.Time; import dconstructor.lifecycles; class TenSecondLifecycle : ILifecycle { override ulong key() { return Clock.now.ticks; } override bool current(ulong key) { auto time = Time.fromTicks(key); return (Clock.now - time).seconds < 10; } }
