diff --git a/CHANGES.md b/CHANGES.md index 338dd97..174e4e1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ Poodinis Changelog ================== **Version 8.1.0-beta.3** * 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** * FIX inheritance type template in custom instance creator (PR #29) diff --git a/source/poodinis/registration.d b/source/poodinis/registration.d index 95d8004..a50a93a 100644 --- a/source/poodinis/registration.d +++ b/source/poodinis/registration.d @@ -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) { registration.instanceFactory.factoryParameters = InstanceFactoryParameters(registration.instanceType, CreatesSingleton.no, null, { @@ -116,6 +116,17 @@ public Registration initializedBy(T : Object)(Registration registration, T deleg 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) { auto concreteTypeListString = ""; foreach (registration ; registrations) { diff --git a/test/poodinis/containertest.d b/test/poodinis/containertest.d index a86062a..5010475 100644 --- a/test/poodinis/containertest.d +++ b/test/poodinis/containertest.d @@ -80,7 +80,7 @@ version(unittest) { 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 { auto container = new shared DependencyContainer(); auto expectedInstance = new TestClass(); @@ -91,6 +91,28 @@ version(unittest) { 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 unittest { auto container = new shared DependencyContainer();