Add initializedOnceBy() to create singleton instances via injection initializer

This commit is contained in:
Mike Bierlee 2021-04-29 01:24:32 +03:00
parent 8f4a64cf4c
commit eaac0eb7ce
3 changed files with 36 additions and 2 deletions

View file

@ -2,6 +2,7 @@ Poodinis Changelog
================== ==================
**Version 8.1.0-beta.3** **Version 8.1.0-beta.3**
* CHANGE injection initializers to be defined as a registration scope instead of via Container.register(). See initializedBy(). * CHANGE injection initializers to be defined as a registration scope instead of via Container.register(). See initializedBy().
* ADD initializedOnceBy() to create singleton instances via injection initializer.
**Version 8.1.0-beta.2** **Version 8.1.0-beta.2**
* FIX inheritance type template in custom instance creator (PR #29) * FIX inheritance type template in custom instance creator (PR #29)

View file

@ -106,7 +106,7 @@ public Registration existingInstance(Registration registration, Object instance)
} }
/** /**
* Scopes registrations to create instances using the given initializer delegate. * Scopes registrations to create new instances using the given initializer delegate.
*/ */
public Registration initializedBy(T : Object)(Registration registration, T delegate() initializer) { public Registration initializedBy(T : Object)(Registration registration, T delegate() initializer) {
registration.instanceFactory.factoryParameters = InstanceFactoryParameters(registration.instanceType, CreatesSingleton.no, null, { registration.instanceFactory.factoryParameters = InstanceFactoryParameters(registration.instanceType, CreatesSingleton.no, null, {
@ -116,6 +116,17 @@ public Registration initializedBy(T : Object)(Registration registration, T deleg
return registration; return registration;
} }
/**
* Scopes registrations to create a new instance using the given initializer delegate. On subsequent resolves the same instance is returned.
*/
public Registration initializedOnceBy(T : Object)(Registration registration, T delegate() initializer) {
registration.instanceFactory.factoryParameters = InstanceFactoryParameters(registration.instanceType, CreatesSingleton.yes, null, {
return cast(Object) initializer();
});
return registration;
}
public string toConcreteTypeListString(Registration[] registrations) { public string toConcreteTypeListString(Registration[] registrations) {
auto concreteTypeListString = ""; auto concreteTypeListString = "";
foreach (registration ; registrations) { foreach (registration ; registrations) {

View file

@ -80,7 +80,7 @@ version(unittest) {
assert(expectedInstance is actualInstance, "Resolved instance from existing instance scope is not the same as the registered instance"); assert(expectedInstance is actualInstance, "Resolved instance from existing instance scope is not the same as the registered instance");
} }
// Test creating instance via customer initializer on resolve // Test creating instance via custom initializer on resolve
unittest { unittest {
auto container = new shared DependencyContainer(); auto container = new shared DependencyContainer();
auto expectedInstance = new TestClass(); auto expectedInstance = new TestClass();
@ -91,6 +91,28 @@ version(unittest) {
assert(expectedInstance is actualInstance, "Resolved instance does not come from the custom initializer"); assert(expectedInstance is actualInstance, "Resolved instance does not come from the custom initializer");
} }
// Test creating instance via initializedBy creates new instance every time
unittest {
auto container = new shared DependencyContainer();
container.register!TestClass.initializedBy({
return new TestClass();
});
auto firstInstance = container.resolve!TestClass;
auto secondInstance = container.resolve!TestClass;
assert(firstInstance !is secondInstance, "Resolved instance are not different instances");
}
// Test creating instance via initializedOnceBy creates a singleton instance
unittest {
auto container = new shared DependencyContainer();
container.register!TestClass.initializedOnceBy({
return new TestClass();
});
auto firstInstance = container.resolve!TestClass;
auto secondInstance = container.resolve!TestClass;
assert(firstInstance is secondInstance, "Resolved instance are different instances");
}
// Test autowire resolved instances // Test autowire resolved instances
unittest { unittest {
auto container = new shared DependencyContainer(); auto container = new shared DependencyContainer();