diff --git a/source/poodinis/autowire.d b/source/poodinis/autowire.d index 58411e0..7ebd618 100644 --- a/source/poodinis/autowire.d +++ b/source/poodinis/autowire.d @@ -180,7 +180,8 @@ private void autowireMember(string member, size_t memberIndex, Type)(shared(Depe private QualifierType createOrResolveInstance(MemberType, QualifierType, bool createNew, bool isOptional)(shared(DependencyContainer) container) { static if (createNew) { - auto instanceFactory = new InstanceFactory(typeid(MemberType), CreatesSingleton.no, null); + auto instanceFactory = new InstanceFactory(); + instanceFactory.factoryParameters = InstanceFactoryParameters(typeid(MemberType), CreatesSingleton.no); return cast(MemberType) instanceFactory.getInstance(); } else { static if (isOptional) { diff --git a/source/poodinis/context.d b/source/poodinis/context.d index 2864929..0054c25 100644 --- a/source/poodinis/context.d +++ b/source/poodinis/context.d @@ -62,7 +62,9 @@ public void registerContextComponents(ApplicationContextType : ApplicationContex registration = container.register!(ReturnType!factoryMethod); } - registration.instanceFactory = new InstanceFactory(registration.instanceType, createsSingleton, null, factoryMethod); + auto instanceFactory = new InstanceFactory(); + instanceFactory.factoryParameters = InstanceFactoryParameters(registration.instanceType, createsSingleton, null, factoryMethod); + registration.instanceFactory = instanceFactory; } } } diff --git a/source/poodinis/factory.d b/source/poodinis/factory.d index 638739c..42fd2fa 100644 --- a/source/poodinis/factory.d +++ b/source/poodinis/factory.d @@ -28,38 +28,53 @@ class InstanceCreationException : Exception { } } -class InstanceFactory { - private TypeInfo_Class instanceType = null; - private Object instance = null; - private CreatesSingleton createsSingleton; - private InstanceFactoryMethod factoryMethod; +struct InstanceFactoryParameters { + TypeInfo_Class instanceType; + CreatesSingleton createsSingleton = CreatesSingleton.yes; + Object existingInstance; + InstanceFactoryMethod factoryMethod; +} - this(TypeInfo_Class instanceType, CreatesSingleton createsSingleton = CreatesSingleton.yes, Object existingInstance = null, InstanceFactoryMethod factoryMethod = null) { - this.instanceType = instanceType; - this.createsSingleton = existingInstance !is null ? CreatesSingleton.yes : createsSingleton; - this.instance = existingInstance; - this.factoryMethod = factoryMethod !is null ? factoryMethod : &this.createInstance; +class InstanceFactory { + private Object instance = null; + private InstanceFactoryParameters _factoryParameters; + + public @property void factoryParameters(InstanceFactoryParameters factoryParameters) { + if (factoryParameters.factoryMethod is null) { + factoryParameters.factoryMethod = &this.createInstance; + } + + if (factoryParameters.existingInstance !is null) { + factoryParameters.createsSingleton = CreatesSingleton.yes; + this.instance = factoryParameters.existingInstance; + } + + this.factoryParameters = factoryParameters; + } + + public @property InstanceFactoryParameters factoryParameters() { + return _factoryParameters; } public Object getInstance() { - if (createsSingleton && instance !is null) { + if (_factoryParameters.createsSingleton && instance !is null) { debug(poodinisVerbose) { - writeln(format("DEBUG: Existing instance returned of type %s", instanceType.toString())); + writeln(format("DEBUG: Existing instance returned of type %s", _factoryParameters.instanceType.toString())); } return instance; } debug(poodinisVerbose) { - writeln(format("DEBUG: Creating new instance of type %s", instanceType.toString())); + writeln(format("DEBUG: Creating new instance of type %s", _factoryParameters.instanceType.toString())); } - instance = factoryMethod(); + instance = _factoryParameters.factoryMethod(); return instance; } private Object createInstance() { - enforce!InstanceCreationException(instanceType, "Instance type is not defined, cannot create instance without knowing its type."); - return instanceType.create(); + enforce!InstanceCreationException(_factoryParameters.instanceType, "Instance type is not defined, cannot create instance without knowing its type."); + return _factoryParameters.instanceType.create(); } } diff --git a/source/poodinis/registration.d b/source/poodinis/registration.d index e451a9b..9922baf 100644 --- a/source/poodinis/registration.d +++ b/source/poodinis/registration.d @@ -67,7 +67,8 @@ class Registration { * Effectively makes the given registration a singleton. */ public Registration singleInstance(Registration registration) { - registration.instanceFactory = new InstanceFactory(registration.instanceType, CreatesSingleton.yes, null); + registration.instanceFactory = new InstanceFactory(); + registration.instanceFactory.factoryParameters = InstanceFactoryParameters(registration.instanceType, CreatesSingleton.yes); return registration; } @@ -75,7 +76,8 @@ public Registration singleInstance(Registration registration) { * Scopes registrations to return a new instance every time the given registration is resolved. */ public Registration newInstance(Registration registration) { - registration.instanceFactory = new InstanceFactory(registration.instanceType, CreatesSingleton.no, null); + registration.instanceFactory = new InstanceFactory(); + registration.instanceFactory.factoryParameters = InstanceFactoryParameters(registration.instanceType, CreatesSingleton.no); return registration; } @@ -83,7 +85,8 @@ public Registration newInstance(Registration registration) { * Scopes registrations to return the given instance every time the given registration is resolved. */ public Registration existingInstance(Registration registration, Object instance) { - registration.instanceFactory = new InstanceFactory(registration.instanceType, CreatesSingleton.yes, instance); + registration.instanceFactory = new InstanceFactory(); + registration.instanceFactory.factoryParameters = InstanceFactoryParameters(registration.instanceType, CreatesSingleton.yes, instance); return registration; } diff --git a/test/poodinis/factorytest.d b/test/poodinis/factorytest.d index 7fe0e9f..1bede46 100644 --- a/test/poodinis/factorytest.d +++ b/test/poodinis/factorytest.d @@ -17,7 +17,8 @@ version(unittest) { // Test instance factory with singletons unittest { - auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.yes, null); + auto factory = new InstanceFactory(); + factory.factoryParameters = InstanceFactoryParameters(typeid(TestImplementation), CreatesSingleton.yes); auto instanceOne = factory.getInstance(); auto instanceTwo = factory.getInstance(); @@ -27,7 +28,8 @@ version(unittest) { // Test instance factory with new instances unittest { - auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.no, null); + auto factory = new InstanceFactory(); + factory.factoryParameters = InstanceFactoryParameters(typeid(TestImplementation), CreatesSingleton.no); auto instanceOne = factory.getInstance(); auto instanceTwo = factory.getInstance(); @@ -38,7 +40,8 @@ version(unittest) { // Test instance factory with existing instances unittest { auto existingInstance = new TestImplementation(); - auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.yes, existingInstance); + auto factory = new InstanceFactory(); + factory.factoryParameters = InstanceFactoryParameters(typeid(TestImplementation), CreatesSingleton.yes, existingInstance); auto instanceOne = factory.getInstance(); auto instanceTwo = factory.getInstance(); @@ -49,7 +52,8 @@ version(unittest) { // Test instance factory with existing instances when setting singleton flag to "no" unittest { auto existingInstance = new TestImplementation(); - auto factory = new InstanceFactory(typeid(TestImplementation), CreatesSingleton.no, existingInstance); + auto factory = new InstanceFactory(); + factory.factoryParameters = InstanceFactoryParameters(typeid(TestImplementation), CreatesSingleton.no, existingInstance); auto instance = factory.getInstance(); assert(instance is existingInstance, "Created factory instance is not the existing instance"); @@ -63,7 +67,8 @@ version(unittest) { return instance; } - auto factory = new InstanceFactory(null, CreatesSingleton.yes, null, &factoryMethod); + auto factory = new InstanceFactory(); + factory.factoryParameters = InstanceFactoryParameters(null, CreatesSingleton.yes, null, &factoryMethod); auto instance = cast(TestImplementation) factory.getInstance(); assert(instance !is null, "No instance was created by factory or could not be cast to expected type");