diff --git a/.vscode/settings.json b/.vscode/settings.json index 2f4238a..c65dfde 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "dfmt.braceStyle": "allman" -} \ No newline at end of file + "dfmt.braceStyle": "otbs" +} diff --git a/README.md b/README.md index 32e6efb..6d527e6 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ import poodinis; class Driver {} -interface Database {}; +interface Database {} class RelationalDatabase : Database { private Driver driver; diff --git a/example/annotations/app.d b/example/annotations/app.d index f466483..15ccafb 100644 --- a/example/annotations/app.d +++ b/example/annotations/app.d @@ -12,53 +12,42 @@ import std.digest.md; import std.stdio; import std.conv; -class SecurityAuditor -{ - public void submitAudit() - { +class SecurityAuditor { + public void submitAudit() { writeln("Hmmmyes I have received your audit. It is.... adequate."); } } -class SuperSecurityDevice -{ +class SuperSecurityDevice { private int seed; - public this() - { + public this() { auto randomGenerator = Random(unpredictableSeed); seed = uniform(0, 999, randomGenerator); } - public string getPassword() - { + public string getPassword() { return to!string(seed) ~ "t1m3sp13!!:"; } } -class SecurityManager -{ +class SecurityManager { @Autowire private SuperSecurityDevice levelOneSecurity; @Autowire @AssignNewInstance private SuperSecurityDevice levelTwoSecurity; @Autowire @OptionalDependency private SecurityAuditor auditor; - public void doAudit() - { - if (auditor !is null) - { + public void doAudit() { + if (auditor !is null) { auditor.submitAudit(); - } - else - { + } else { writeln("I uh, will skip the audit for now..."); } } } -void main() -{ +void main() { auto dependencies = new shared DependencyContainer(); dependencies.register!SuperSecurityDevice; // Registered with the default "Single instance" scope dependencies.register!SecurityManager; @@ -68,12 +57,9 @@ void main() writeln("Password for user one: " ~ manager.levelOneSecurity.getPassword()); writeln("Password for user two: " ~ manager.levelTwoSecurity.getPassword()); - if (manager.levelOneSecurity is manager.levelTwoSecurity) - { + if (manager.levelOneSecurity is manager.levelTwoSecurity) { writeln("SECURITY BREACH!!!!!"); // Should not be printed since levelTwoSecurity is a new instance. - } - else - { + } else { writeln("Security okay!"); } diff --git a/example/applicationcontext/app.d b/example/applicationcontext/app.d index 04242a0..654fe23 100644 --- a/example/applicationcontext/app.d +++ b/example/applicationcontext/app.d @@ -9,64 +9,50 @@ import poodinis; import std.stdio; -class TownSquare -{ - +class TownSquare { @Autowire private MarketStall marketStall; - public void makeSound() - { + public void makeSound() { marketStall.announceGoodsForSale(); } } -interface Goods -{ +interface Goods { public string getGoodsName(); } -class Fish : Goods -{ - public override string getGoodsName() - { +class Fish : Goods { + public override string getGoodsName() { return "Fish"; } } -class MarketStall -{ +class MarketStall { private Goods goods; - this(Goods goods) - { + this(Goods goods) { this.goods = goods; } - public void announceGoodsForSale() - { + public void announceGoodsForSale() { writeln(goods.getGoodsName() ~ " for sale!"); } } -class ExampleApplicationContext : ApplicationContext -{ - +class ExampleApplicationContext : ApplicationContext { @Autowire private Goods goods; - public override void registerDependencies(shared(DependencyContainer) container) - { + public override void registerDependencies(shared(DependencyContainer) container) { container.register!(Goods, Fish); container.register!TownSquare; } - @Component public MarketStall marketStall() - { + @Component public MarketStall marketStall() { return new MarketStall(goods); } } -void main() -{ +void main() { auto container = new shared DependencyContainer(); container.registerContext!ExampleApplicationContext; diff --git a/example/arraycompletion/app.d b/example/arraycompletion/app.d index ddc3383..267f4c0 100644 --- a/example/arraycompletion/app.d +++ b/example/arraycompletion/app.d @@ -9,50 +9,39 @@ import poodinis; import std.stdio; -interface Pie -{ +interface Pie { public void eat(); } -class BlueBerryPie : Pie -{ - public override void eat() - { +class BlueBerryPie : Pie { + public override void eat() { writeln("Nom nom nom. I like this one!"); } } -class ApplePie : Pie -{ - public override void eat() - { +class ApplePie : Pie { + public override void eat() { writeln("Nom nom nom. These aren't real apples..."); } } -class CardboardBoxPie : Pie -{ - public override void eat() - { +class CardboardBoxPie : Pie { + public override void eat() { writeln("Nom nom nom. This... is not a pie."); } } -class PieEater -{ +class PieEater { @Autowire private Pie[] pies; - public void eatThemAll() - { - foreach (pie; pies) - { + public void eatThemAll() { + foreach (pie; pies) { pie.eat(); } } } -void main() -{ +void main() { auto dependencies = new shared DependencyContainer(); dependencies.register!(Pie, BlueBerryPie); dependencies.register!(Pie, ApplePie); diff --git a/example/constructorinjection/app.d b/example/constructorinjection/app.d index 682d4f5..000c437 100644 --- a/example/constructorinjection/app.d +++ b/example/constructorinjection/app.d @@ -7,64 +7,52 @@ import std.stdio; -class Scheduler -{ +class Scheduler { private Calendar calendar; // All parameters will autmatically be assigned when Scheduler is created. - this(Calendar calendar) - { + this(Calendar calendar) { this.calendar = calendar; } - public void scheduleJob() - { + public void scheduleJob() { calendar.findOpenDate(); } } -class Calendar -{ +class Calendar { private HardwareClock hardwareClock; // This constructor contains built-in type "int" and thus will not be used. - this(int initialDateTimeStamp, HardwareClock hardwareClock) - { + this(int initialDateTimeStamp, HardwareClock hardwareClock) { } // This constructor is chosen instead as candidate for injection when Calendar is created. - this(HardwareClock hardwareClock) - { + this(HardwareClock hardwareClock) { this.hardwareClock = hardwareClock; } - public void findOpenDate() - { + public void findOpenDate() { hardwareClock.doThings(); } } -class HardwareClock -{ +class HardwareClock { // Parameterless constructors will halt any further selection of constructors. - this() - { + this() { } // As a result, this constructor will not be used when HardwareClock is created. - this(Calendar calendar) - { + this(Calendar calendar) { throw new Exception("This constructor should not be used by Poodinis"); } - public void doThings() - { + public void doThings() { writeln("Things are being done!"); } } -void main() -{ +void main() { import poodinis; // Locally imported to emphasize that classes do not depend on Poodinis. auto dependencies = new shared DependencyContainer(); diff --git a/example/injectioninitializer/app.d b/example/injectioninitializer/app.d index 1519e61..b26fc29 100644 --- a/example/injectioninitializer/app.d +++ b/example/injectioninitializer/app.d @@ -8,12 +8,10 @@ import poodinis; import std.stdio; -class Doohickey -{ +class Doohickey { } -void main() -{ +void main() { auto dependencies = new shared DependencyContainer(); dependencies.register!Doohickey.initializedBy({ writeln("Creating Doohickey via initializer delegate."); diff --git a/example/postconstructorpredestructor/app.d b/example/postconstructorpredestructor/app.d index 7a16c29..2e286e6 100644 --- a/example/postconstructorpredestructor/app.d +++ b/example/postconstructorpredestructor/app.d @@ -9,44 +9,34 @@ import poodinis; import std.stdio; -class ADependency -{ - @PostConstruct public void postConstructor() - { +class ADependency { + @PostConstruct public void postConstructor() { writeln("The dependency is created."); } - public void callMe() - { + public void callMe() { writeln("The dependency was called."); } } -class AClass -{ +class AClass { @Autowire public ADependency dependency; // Dependencies are autowired before the post-constructor is called. - @PostConstruct public void postConstructor() - { + @PostConstruct public void postConstructor() { writeln("The class is created."); - if (dependency !is null) - { + if (dependency !is null) { writeln("The dependency is autowired."); - } - else - { + } else { writeln("The dependency was NOT autowired."); } } - @PreDestroy public void preDestructor() - { + @PreDestroy public void preDestructor() { writeln("The class is no longer registered with the container."); } } -public void main() -{ +public void main() { auto container = new shared DependencyContainer(); container.register!(ADependency).onConstructed((Object obj) { writeln("ADependency constructed"); diff --git a/example/qualifiers/app.d b/example/qualifiers/app.d index 0c169cf..ef43070 100644 --- a/example/qualifiers/app.d +++ b/example/qualifiers/app.d @@ -9,50 +9,39 @@ import poodinis; import std.stdio; -interface Engine -{ +interface Engine { public void engage(); } -class FuelEngine : Engine -{ - public void engage() - { +class FuelEngine : Engine { + public void engage() { writeln("VROOOOOOM!"); } } -class ElectricEngine : Engine -{ - public void engage() - { +class ElectricEngine : Engine { + public void engage() { writeln("hummmmmmmm...."); } } -class HybridCar -{ +class HybridCar { alias KilometersPerHour = int; @Autowire!FuelEngine private Engine fuelEngine; @Autowire!ElectricEngine private Engine electricEngine; - public void moveAtSpeed(KilometersPerHour speed) - { - if (speed <= 45) - { + public void moveAtSpeed(KilometersPerHour speed) { + if (speed <= 45) { electricEngine.engage(); - } - else - { + } else { fuelEngine.engage(); } } } -void main() -{ +void main() { auto dependencies = new shared DependencyContainer(); dependencies.register!HybridCar; diff --git a/example/quickstart/app.d b/example/quickstart/app.d index 979f679..19e6795 100644 --- a/example/quickstart/app.d +++ b/example/quickstart/app.d @@ -7,31 +7,25 @@ import poodinis; -class Driver -{ +class Driver { } -interface Database -{ +interface Database { } -class RelationalDatabase : Database -{ +class RelationalDatabase : Database { private Driver driver; - this(Driver driver) - { // Automatically injected on creation by container + this(Driver driver) { // Automatically injected on creation by container this.driver = driver; } } -class DataWriter -{ +class DataWriter { @Autowire private Database database; // Automatically injected when class is resolved } -void main() -{ +void main() { auto dependencies = new shared DependencyContainer(); dependencies.register!Driver; dependencies.register!DataWriter; diff --git a/example/registeronresolve/app.d b/example/registeronresolve/app.d index b87d4b5..be72c43 100644 --- a/example/registeronresolve/app.d +++ b/example/registeronresolve/app.d @@ -7,28 +7,23 @@ import poodinis; -class Violin -{ +class Violin { } -interface InstrumentPlayer -{ +interface InstrumentPlayer { } -class ViolinPlayer : InstrumentPlayer -{ +class ViolinPlayer : InstrumentPlayer { // Autowired concrete types can be registered on resolve @Autowire private Violin violin; } -class Orchestra -{ +class Orchestra { // Autowired non-concrete types can be registered on resolved, given they have a qualifier. @Autowire!ViolinPlayer private InstrumentPlayer violinPlayer; } -void main() -{ +void main() { auto dependencies = new shared DependencyContainer(); /* diff --git a/example/valueinjection/app.d b/example/valueinjection/app.d index a635dc7..643ce95 100644 --- a/example/valueinjection/app.d +++ b/example/valueinjection/app.d @@ -10,12 +10,9 @@ import poodinis; import std.stdio; import std.string; -class IntValueInjector : ValueInjector!int -{ - int get(string key) - { - switch (key) - { +class IntValueInjector : ValueInjector!int { + int get(string key) { + switch (key) { case "http.port": return 8080; case "http.keep_alive": @@ -26,12 +23,9 @@ class IntValueInjector : ValueInjector!int } } -class StringValueInjector : ValueInjector!string -{ - string get(string key) - { - switch (key) - { +class StringValueInjector : ValueInjector!string { + string get(string key) { + switch (key) { case "http.hostname": return "acme.org"; default: @@ -40,8 +34,7 @@ class StringValueInjector : ValueInjector!string } } -class HttpServer -{ +class HttpServer { @Value("http.port") private int port = 80; @@ -55,15 +48,13 @@ class HttpServer @MandatoryValue("http.keep_alive") private int keepAliveTime; // A ResolveException is thrown when the value is not available, default assignments are not used. - public void serve() - { + public void serve() { writeln(format("Serving pages for %s:%s with max connection count of %s", hostName, port, maxConnections)); } } -void main() -{ +void main() { auto dependencies = new shared DependencyContainer(); dependencies.register!(ValueInjector!int, IntValueInjector); dependencies.register!(ValueInjector!string, StringValueInjector); diff --git a/source/poodinis/altphobos.d b/source/poodinis/altphobos.d index 5a6a4e4..a474b3f 100644 --- a/source/poodinis/altphobos.d +++ b/source/poodinis/altphobos.d @@ -20,25 +20,17 @@ module poodinis.altphobos; -template isFunction(X...) -{ - static if (X.length == 1) - { - static if (is(typeof(&X[0]) U : U*) && is(U == function) || is(typeof(&X[0]) U == delegate)) - { +template isFunction(X...) { + static if (X.length == 1) { + static if (is(typeof(&X[0]) U : U*) && is(U == function) || is(typeof(&X[0]) U == delegate)) { // x is a (nested) function symbol. enum isFunction = true; - } - else static if (is(X[0] T)) - { + } else static if (is(X[0] T)) { // x is a type. Take the type of it and examine. enum isFunction = is(T == function); - } - else + } else enum isFunction = false; - } - else - { + } else { enum isFunction = false; } } diff --git a/source/poodinis/autowire.d b/source/poodinis/autowire.d index 31bd771..01939ff 100644 --- a/source/poodinis/autowire.d +++ b/source/poodinis/autowire.d @@ -30,13 +30,11 @@ import std.string : format; import std.traits : BaseClassesTuple, FieldNameTuple, fullyQualifiedName, hasUDA, isDynamicArray; import std.range : ElementType; -debug -{ +debug { import std.stdio : writeln; } -private struct UseMemberType -{ +private struct UseMemberType { } /** @@ -72,8 +70,7 @@ private struct UseMemberType * autowire member "fuelEngine" as if it's of type "FuelEngine". This means that the members of instance "fuelEngine" * will also be autowired because the autowire mechanism knows that member "fuelEngine" is an instance of "FuelEngine" */ -struct Autowire(QualifierType) -{ +struct Autowire(QualifierType) { QualifierType qualifier; } @@ -82,8 +79,7 @@ struct Autowire(QualifierType) * Optional dependencies will not lead to a resolveException when there is no type registered for them. * The member will remain null. */ -struct OptionalDependency -{ +struct OptionalDependency { } /** @@ -99,14 +95,11 @@ struct OptionalDependency *--- * antenna will always be assigned a new instance of class Antenna. */ -struct AssignNewInstance -{ +struct AssignNewInstance { } -private void printDebugAutowiredInstance(TypeInfo instanceType, void* instanceAddress) -{ - debug - { +private void printDebugAutowiredInstance(TypeInfo instanceType, void* instanceAddress) { + debug { writeln(format("DEBUG: Autowiring members of [%s@%s]", instanceType, instanceAddress)); } } @@ -120,65 +113,48 @@ private void printDebugAutowiredInstance(TypeInfo instanceType, void* instanceAd * * See_Also: Autowire */ -public void autowire(Type)(shared(DependencyContainer) container, Type instance) -{ - debug (poodinisVerbose) - { +public void autowire(Type)(shared(DependencyContainer) container, Type instance) { + debug (poodinisVerbose) { printDebugAutowiredInstance(typeid(Type), &instance); } // Recurse into base class if there are more between Type and Object in the hierarchy - static if (BaseClassesTuple!Type.length > 1) - { + static if (BaseClassesTuple!Type.length > 1) { autowire!(BaseClassesTuple!Type[0])(container, instance); } - foreach (index, name; FieldNameTuple!Type) - { + foreach (index, name; FieldNameTuple!Type) { autowireMember!(name, index, Type)(container, instance); } } private void printDebugAutowiringCandidate(TypeInfo candidateInstanceType, - void* candidateInstanceAddress, TypeInfo instanceType, void* instanceAddress, string member) -{ - debug - { + void* candidateInstanceAddress, TypeInfo instanceType, void* instanceAddress, string member) { + debug { writeln(format("DEBUG: Autowired instance [%s@%s] to [%s@%s].%s", candidateInstanceType, candidateInstanceAddress, instanceType, instanceAddress, member)); } } private void printDebugAutowiringArray(TypeInfo superTypeInfo, - TypeInfo instanceType, void* instanceAddress, string member) -{ - debug - { + TypeInfo instanceType, void* instanceAddress, string member) { + debug { writeln(format("DEBUG: Autowired all registered instances of super type %s to [%s@%s].%s", superTypeInfo, instanceType, instanceAddress, member)); } } private void autowireMember(string member, size_t memberIndex, Type)( - shared(DependencyContainer) container, Type instance) -{ - foreach (attribute; __traits(getAttributes, Type.tupleof[memberIndex])) - { - static if (is(attribute == Autowire!T, T)) - { + shared(DependencyContainer) container, Type instance) { + foreach (attribute; __traits(getAttributes, Type.tupleof[memberIndex])) { + static if (is(attribute == Autowire!T, T)) { injectInstance!(member, memberIndex, typeof(attribute.qualifier))(container, instance); - } - else static if (__traits(isSame, attribute, Autowire)) - { + } else static if (__traits(isSame, attribute, Autowire)) { injectInstance!(member, memberIndex, UseMemberType)(container, instance); - } - else static if (is(typeof(attribute) == Value)) - { + } else static if (is(typeof(attribute) == Value)) { enum key = attribute.key; injectValue!(member, memberIndex, key, false)(container, instance); - } - else static if (is(typeof(attribute) == MandatoryValue)) - { + } else static if (is(typeof(attribute) == MandatoryValue)) { enum key = attribute.key; injectValue!(member, memberIndex, key, true)(container, instance); } @@ -186,20 +162,15 @@ private void autowireMember(string member, size_t memberIndex, Type)( } private void injectInstance(string member, size_t memberIndex, QualifierType, Type)( - shared(DependencyContainer) container, Type instance) -{ - if (instance.tupleof[memberIndex] is null) - { + shared(DependencyContainer) container, Type instance) { + if (instance.tupleof[memberIndex] is null) { alias MemberType = typeof(Type.tupleof[memberIndex]); enum isOptional = hasUDA!(Type.tupleof[memberIndex], OptionalDependency); - static if (isDynamicArray!MemberType) - { + static if (isDynamicArray!MemberType) { injectMultipleInstances!(member, memberIndex, isOptional, MemberType)(container, instance); - } - else - { + } else { injectSingleInstance!(member, memberIndex, isOptional, MemberType, QualifierType)(container, instance); } @@ -207,107 +178,80 @@ private void injectInstance(string member, size_t memberIndex, QualifierType, Ty } private void injectMultipleInstances(string member, size_t memberIndex, - bool isOptional, MemberType, Type)(shared(DependencyContainer) container, Type instance) -{ + bool isOptional, MemberType, Type)(shared(DependencyContainer) container, Type instance) { alias MemberElementType = ElementType!MemberType; - static if (isOptional) - { + static if (isOptional) { auto instances = container.resolveAll!MemberElementType(ResolveOption.noResolveException); - } - else - { + } else { auto instances = container.resolveAll!MemberElementType; } instance.tupleof[memberIndex] = instances; - debug (poodinisVerbose) - { + debug (poodinisVerbose) { printDebugAutowiringArray(typeid(MemberElementType), typeid(Type), &instance, member); } } private void injectSingleInstance(string member, size_t memberIndex, bool isOptional, MemberType, QualifierType, Type)( - shared(DependencyContainer) container, Type instance) -{ - debug (poodinisVerbose) - { + shared(DependencyContainer) container, Type instance) { + debug (poodinisVerbose) { TypeInfo qualifiedInstanceType = typeid(MemberType); } enum assignNewInstance = hasUDA!(Type.tupleof[memberIndex], AssignNewInstance); MemberType qualifiedInstance; - static if (!is(QualifierType == UseMemberType)) - { + static if (!is(QualifierType == UseMemberType)) { qualifiedInstance = createOrResolveInstance!(MemberType, QualifierType, assignNewInstance, isOptional)(container); - debug (poodinisVerbose) - { + debug (poodinisVerbose) { qualifiedInstanceType = typeid(QualifierType); } - } - else - { + } else { qualifiedInstance = createOrResolveInstance!(MemberType, MemberType, assignNewInstance, isOptional)(container); } instance.tupleof[memberIndex] = qualifiedInstance; - debug (poodinisVerbose) - { + debug (poodinisVerbose) { printDebugAutowiringCandidate(qualifiedInstanceType, &qualifiedInstance, typeid(Type), &instance, member); } } private QualifierType createOrResolveInstance(MemberType, QualifierType, - bool createNew, bool isOptional)(shared(DependencyContainer) container) -{ - static if (createNew) - { + bool createNew, bool isOptional)(shared(DependencyContainer) container) { + static if (createNew) { auto instanceFactory = new InstanceFactory(); instanceFactory.factoryParameters = InstanceFactoryParameters(typeid(MemberType), CreatesSingleton.no); return cast(MemberType) instanceFactory.getInstance(); - } - else - { - static if (isOptional) - { + } else { + static if (isOptional) { return container.resolve!(MemberType, QualifierType)(ResolveOption.noResolveException); - } - else - { + } else { return container.resolve!(MemberType, QualifierType); } } } private void injectValue(string member, size_t memberIndex, string key, bool mandatory, Type)( - shared(DependencyContainer) container, Type instance) -{ + shared(DependencyContainer) container, Type instance) { alias MemberType = typeof(Type.tupleof[memberIndex]); - try - { + try { auto injector = container.resolve!(ValueInjector!MemberType); instance.tupleof[memberIndex] = injector.get(key); - debug (poodinisVerbose) - { + debug (poodinisVerbose) { printDebugValueInjection(typeid(Type), &instance, member, typeid(MemberType), key); } - } - catch (ResolveException e) - { + } catch (ResolveException e) { throw new ValueInjectionException(format( "Could not inject value of type %s into %s.%s: value injector is missing for this type.", typeid(MemberType), typeid(Type), member)); - } - catch (ValueNotAvailableException e) - { - static if (mandatory) - { + } catch (ValueNotAvailableException e) { + static if (mandatory) { throw new ValueInjectionException(format("Could not inject value of type %s into %s.%s", typeid(MemberType), typeid(Type), member), e); } @@ -315,10 +259,8 @@ private void injectValue(string member, size_t memberIndex, string key, bool man } private void printDebugValueInjection(TypeInfo instanceType, - void* instanceAddress, string member, TypeInfo valueType, string key) -{ - debug - { + void* instanceAddress, string member, TypeInfo valueType, string key) { + debug { writeln(format("DEBUG: Injected value with key '%s' of type %s into [%s@%s].%s", key, valueType, instanceType, instanceAddress, member)); } @@ -330,24 +272,20 @@ private void printDebugValueInjection(TypeInfo instanceType, * See_Also: DependencyContainer * Deprecated: Using the global container is undesired. See DependencyContainer.getInstance(). */ -public deprecated void globalAutowire(Type)(Type instance) -{ +public deprecated void globalAutowire(Type)(Type instance) { DependencyContainer.getInstance().autowire(instance); } -class AutowiredRegistration(RegistrationType : Object) : Registration -{ +class AutowiredRegistration(RegistrationType : Object) : Registration { private shared(DependencyContainer) container; public this(TypeInfo registeredType, InstanceFactory instanceFactory, - shared(DependencyContainer) originatingContainer) - { + shared(DependencyContainer) originatingContainer) { super(registeredType, typeid(RegistrationType), instanceFactory, originatingContainer); } public override Object getInstance( - InstantiationContext context = new AutowireInstantiationContext()) - { + InstantiationContext context = new AutowireInstantiationContext()) { enforce(!(originatingContainer is null), "The registration's originating container is null. There is no way to resolve autowire dependencies."); @@ -355,8 +293,7 @@ class AutowiredRegistration(RegistrationType : Object) : Registration AutowireInstantiationContext autowireContext = cast(AutowireInstantiationContext) context; enforce(!(autowireContext is null), "Given instantiation context type could not be cast to an AutowireInstantiationContext. If you relied on using the default assigned context: make sure you're calling getInstance() on an instance of type AutowiredRegistration!"); - if (autowireContext.autowireInstance) - { + if (autowireContext.autowireInstance) { originatingContainer.autowire(instance); } @@ -365,18 +302,14 @@ class AutowiredRegistration(RegistrationType : Object) : Registration return instance; } - private void delegate() getPreDestructor(RegistrationType instance) - { + private void delegate() getPreDestructor(RegistrationType instance) { void delegate() preDestructor = null; - foreach (memberName; __traits(allMembers, RegistrationType)) - { - foreach (overload; __traits(getOverloads, instance, memberName)) - { + foreach (memberName; __traits(allMembers, RegistrationType)) { + foreach (overload; __traits(getOverloads, instance, memberName)) { static if (__traits(compiles, __traits(getProtection, overload)) && __traits(getProtection, overload) == "public" && isFunction!overload - && hasUDA!(overload, PreDestroy)) - { + && hasUDA!(overload, PreDestroy)) { preDestructor = &__traits(getMember, instance, memberName); } } @@ -386,7 +319,6 @@ class AutowiredRegistration(RegistrationType : Object) : Registration } } -class AutowireInstantiationContext : InstantiationContext -{ +class AutowireInstantiationContext : InstantiationContext { public bool autowireInstance = true; } diff --git a/source/poodinis/container.d b/source/poodinis/container.d index 30d4c2c..d3fc353 100644 --- a/source/poodinis/container.d +++ b/source/poodinis/container.d @@ -26,23 +26,19 @@ import std.algorithm : canFind; import std.traits : fullyQualifiedName, hasUDA, BaseTypeTuple; import std.meta : AliasSeq; -debug (poodinisVerbose) -{ +debug (poodinisVerbose) { import std.stdio : writeln; } /** * Exception thrown when errors occur while resolving a type in a dependency container. */ -class ResolveException : Exception -{ - this(string message, TypeInfo resolveType) - { +class ResolveException : Exception { + this(string message, TypeInfo resolveType) { super(format("Exception while resolving type %s: %s", resolveType.toString(), message)); } - this(Throwable cause, TypeInfo resolveType) - { + this(Throwable cause, TypeInfo resolveType) { super(format("Exception while resolving type %s", resolveType.toString()), cause); } } @@ -50,10 +46,8 @@ class ResolveException : Exception /** * Exception thrown when errors occur while registering a type in a dependency container. */ -class RegistrationException : Exception -{ - this(string message, TypeInfo registrationType) - { +class RegistrationException : Exception { + this(string message, TypeInfo registrationType) { super(format("Exception while registering type %s: %s", registrationType.toString(), message)); } @@ -62,8 +56,7 @@ class RegistrationException : Exception /** * Options which influence the process of registering dependencies */ -public enum RegistrationOption -{ +public enum RegistrationOption { none = 0, /** * Prevent a concrete type being registered on itself. With this option you will always need @@ -75,8 +68,7 @@ public enum RegistrationOption /** * Options which influence the process of resolving dependencies */ -public enum ResolveOption -{ +public enum ResolveOption { none = 0, /** * Registers the type you're trying to resolve before returning it. @@ -99,8 +91,7 @@ public enum ResolveOption * Multiple methods can be marked and will all be called after construction. The order in which * methods are called is undetermined. Methods should have the signature void(void). */ -struct PostConstruct -{ +struct PostConstruct { } /** @@ -110,8 +101,7 @@ struct PostConstruct * This method is called when removeRegistration or clearAllRegistrations is called. * It will also be called when the container's destructor is called. */ -struct PreDestroy -{ +struct PreDestroy { } /** @@ -124,8 +114,7 @@ struct PreDestroy * In most cases you want to use a global singleton dependency container provided by getInstance() to manage all dependencies. * You can still create new instances of this class for exceptional situations. */ -synchronized class DependencyContainer -{ +synchronized class DependencyContainer { private Registration[][TypeInfo] registrations; private Registration[] autowireStack; @@ -133,8 +122,7 @@ synchronized class DependencyContainer private RegistrationOption persistentRegistrationOptions; private ResolveOption persistentResolveOptions; - ~this() - { + ~this() { clearAllRegistrations(); } @@ -158,8 +146,7 @@ synchronized class DependencyContainer * * See_Also: singleInstance, newInstance, existingInstance */ - public Registration register(ConcreteType)(RegistrationOption options = RegistrationOption.none) - { + public Registration register(ConcreteType)(RegistrationOption options = RegistrationOption.none) { return register!(ConcreteType, ConcreteType)(options); } @@ -182,20 +169,17 @@ synchronized class DependencyContainer */ public Registration register(SuperType, ConcreteType: SuperType)(RegistrationOption options = RegistrationOption.none) - if (!is(ConcreteType == struct)) - { + if (!is(ConcreteType == struct)) { TypeInfo registeredType = typeid(SuperType); TypeInfo_Class concreteType = typeid(ConcreteType); - debug (poodinisVerbose) - { + debug (poodinisVerbose) { writeln(format("DEBUG: Register type %s (as %s)", concreteType.toString(), registeredType.toString())); } auto existingRegistration = getExistingRegistration(registeredType, concreteType); - if (existingRegistration) - { + if (existingRegistration) { return existingRegistration; } @@ -204,11 +188,9 @@ synchronized class DependencyContainer instanceFactory, this); newRegistration.initializeFactoryType().singleInstance(); - static if (!is(SuperType == ConcreteType)) - { + static if (!is(SuperType == ConcreteType)) { if (!hasOption(options, persistentRegistrationOptions, - RegistrationOption.doNotAddConcreteTypeRegistration)) - { + RegistrationOption.doNotAddConcreteTypeRegistration)) { auto concreteTypeRegistration = register!ConcreteType; concreteTypeRegistration.linkTo(newRegistration); } @@ -219,38 +201,30 @@ synchronized class DependencyContainer } private bool hasOption(OptionType)(OptionType options, - OptionType persistentOptions, OptionType option) - { + OptionType persistentOptions, OptionType option) { return ((options | persistentOptions) & option) != 0; } - private OptionType buildFlags(OptionType)(OptionType[] options) - { + private OptionType buildFlags(OptionType)(OptionType[] options) { OptionType flags; - foreach (option; options) - { + foreach (option; options) { flags |= option; } return flags; } - private Registration getExistingRegistration(TypeInfo registrationType, TypeInfo qualifierType) - { + private Registration getExistingRegistration(TypeInfo registrationType, TypeInfo qualifierType) { auto existingCandidates = registrationType in registrations; - if (existingCandidates) - { + if (existingCandidates) { return getRegistration(cast(Registration[])*existingCandidates, qualifierType); } return null; } - private Registration getRegistration(Registration[] candidates, TypeInfo concreteType) - { - foreach (existingRegistration; candidates) - { - if (existingRegistration.instanceType == concreteType) - { + private Registration getRegistration(Registration[] candidates, TypeInfo concreteType) { + foreach (existingRegistration; candidates) { + if (existingRegistration.instanceType == concreteType) { return existingRegistration; } } @@ -299,8 +273,7 @@ synchronized class DependencyContainer */ public RegistrationType resolve(RegistrationType)( ResolveOption resolveOptions = ResolveOption.none) - if (!is(RegistrationType == struct)) - { + if (!is(RegistrationType == struct)) { return resolve!(RegistrationType, RegistrationType)(resolveOptions); } @@ -332,32 +305,26 @@ synchronized class DependencyContainer */ public QualifierType resolve(RegistrationType, QualifierType: RegistrationType)(ResolveOption resolveOptions = ResolveOption.none) - if (!is(QualifierType == struct)) - { + if (!is(QualifierType == struct)) { TypeInfo resolveType = typeid(RegistrationType); TypeInfo qualifierType = typeid(QualifierType); - debug (poodinisVerbose) - { + debug (poodinisVerbose) { writeln("DEBUG: Resolving type " ~ resolveType.toString() ~ " with qualifier " ~ qualifierType.toString()); } auto candidates = resolveType in registrations; - if (!candidates) - { - static if (is(typeof(typeid(QualifierType)) == TypeInfo_Class) && !__traits(isAbstractClass, QualifierType)) - { + if (!candidates) { + static if (is(typeof(typeid(QualifierType)) == TypeInfo_Class) && !__traits(isAbstractClass, QualifierType)) { if (hasOption(resolveOptions, persistentResolveOptions, ResolveOption - .registerBeforeResolving)) - { + .registerBeforeResolving)) { register!(RegistrationType, QualifierType)(); return resolve!(RegistrationType, QualifierType)(resolveOptions); } } if (hasOption(resolveOptions, persistentResolveOptions, - ResolveOption.noResolveException)) - { + ResolveOption.noResolveException)) { return null; } @@ -367,37 +334,29 @@ synchronized class DependencyContainer Registration registration = getQualifiedRegistration(resolveType, qualifierType, cast(Registration[])*candidates); - try - { + try { QualifierType newInstance = resolveAutowiredInstance!QualifierType(registration); callPostConstructors(newInstance); return newInstance; - } - catch (ValueInjectionException e) - { + } catch (ValueInjectionException e) { throw new ResolveException(e, resolveType); } } - bool isRegistered(RegistrationType)() - { + bool isRegistered(RegistrationType)() { TypeInfo typeInfo = typeid(RegistrationType); auto candidates = typeInfo in registrations; return candidates !is null; } - private QualifierType resolveAutowiredInstance(QualifierType)(Registration registration) - { + private QualifierType resolveAutowiredInstance(QualifierType)(Registration registration) { QualifierType instance; - if (!(cast(Registration[]) autowireStack).canFind(registration)) - { + if (!(cast(Registration[]) autowireStack).canFind(registration)) { autowireStack ~= cast(shared(Registration)) registration; instance = cast(QualifierType) registration.getInstance( new AutowireInstantiationContext()); autowireStack = autowireStack[0 .. $ - 1]; - } - else - { + } else { auto autowireContext = new AutowireInstantiationContext(); autowireContext.autowireInstance = false; instance = cast(QualifierType) registration.getInstance(autowireContext); @@ -423,25 +382,21 @@ synchronized class DependencyContainer * --- */ public RegistrationType[] resolveAll(RegistrationType)( - ResolveOption resolveOptions = ResolveOption.none) - { + ResolveOption resolveOptions = ResolveOption.none) { RegistrationType[] instances; TypeInfo resolveType = typeid(RegistrationType); auto qualifiedRegistrations = resolveType in registrations; - if (!qualifiedRegistrations) - { + if (!qualifiedRegistrations) { if (hasOption(resolveOptions, persistentResolveOptions, - ResolveOption.noResolveException)) - { + ResolveOption.noResolveException)) { return []; } throw new ResolveException("Type not registered.", resolveType); } - foreach (registration; cast(Registration[])*qualifiedRegistrations) - { + foreach (registration; cast(Registration[])*qualifiedRegistrations) { instances ~= resolveAutowiredInstance!RegistrationType(registration); } @@ -449,12 +404,9 @@ synchronized class DependencyContainer } private Registration getQualifiedRegistration(TypeInfo resolveType, - TypeInfo qualifierType, Registration[] candidates) - { - if (resolveType == qualifierType) - { - if (candidates.length > 1) - { + TypeInfo qualifierType, Registration[] candidates) { + if (resolveType == qualifierType) { + if (candidates.length > 1) { string candidateList = candidates.toConcreteTypeListString(); throw new ResolveException( "Multiple qualified candidates available: " ~ candidateList ~ ". Please use a qualifier.", @@ -467,17 +419,13 @@ synchronized class DependencyContainer return getRegistration(candidates, qualifierType); } - private void callPostConstructors(Type)(Type instance) - { - foreach (memberName; __traits(allMembers, Type)) - { - foreach (overload; __traits(getOverloads, instance, memberName)) - { + private void callPostConstructors(Type)(Type instance) { + foreach (memberName; __traits(allMembers, Type)) { + foreach (overload; __traits(getOverloads, instance, memberName)) { static if (__traits(compiles, __traits(getProtection, overload)) && __traits(getProtection, overload) == "public" && isFunction!overload - && hasUDA!(overload, PostConstruct)) - { + && hasUDA!(overload, PostConstruct)) { __traits(getMember, instance, memberName)(); } } @@ -487,10 +435,8 @@ synchronized class DependencyContainer /** * Clears all dependency registrations managed by this container. */ - public void clearAllRegistrations() - { - foreach (registrationsOfType; registrations) - { + public void clearAllRegistrations() { + foreach (registrationsOfType; registrations) { callPreDestructorsOfRegistrations(registrationsOfType); } registrations.destroy(); @@ -506,20 +452,16 @@ synchronized class DependencyContainer * container.removeRegistration!Animal; * --- */ - public void removeRegistration(RegistrationType)() - { + public void removeRegistration(RegistrationType)() { auto registrationsOfType = *(typeid(RegistrationType) in registrations); callPreDestructorsOfRegistrations(registrationsOfType); registrations.remove(typeid(RegistrationType)); } - private void callPreDestructorsOfRegistrations(shared(Registration[]) registrations) - { - foreach (registration; registrations) - { + private void callPreDestructorsOfRegistrations(shared(Registration[]) registrations) { + foreach (registration; registrations) { Registration unsharedRegistration = cast(Registration) registration; - if (unsharedRegistration.preDestructor !is null) - { + if (unsharedRegistration.preDestructor !is null) { unsharedRegistration.preDestructor()(); } } @@ -528,32 +470,28 @@ synchronized class DependencyContainer /** * Apply persistent registration options which will be used everytime register() is called. */ - public void setPersistentRegistrationOptions(RegistrationOption options) - { + public void setPersistentRegistrationOptions(RegistrationOption options) { persistentRegistrationOptions = options; } /** * Unsets all applied persistent registration options */ - public void unsetPersistentRegistrationOptions() - { + public void unsetPersistentRegistrationOptions() { persistentRegistrationOptions = RegistrationOption.none; } /** * Apply persistent resolve options which will be used everytime resolve() is called. */ - public void setPersistentResolveOptions(ResolveOption options) - { + public void setPersistentResolveOptions(ResolveOption options) { persistentResolveOptions = options; } /** * Unsets all applied persistent resolve options */ - public void unsetPersistentResolveOptions() - { + public void unsetPersistentResolveOptions() { persistentResolveOptions = ResolveOption.none; } diff --git a/source/poodinis/context.d b/source/poodinis/context.d index 148d4a3..522b539 100644 --- a/source/poodinis/context.d +++ b/source/poodinis/context.d @@ -20,10 +20,8 @@ import poodinis.autowire : autowire; import std.traits : hasUDA, ReturnType; -class ApplicationContext -{ - public void registerDependencies(shared(DependencyContainer) container) - { +class ApplicationContext { + public void registerDependencies(shared(DependencyContainer) container) { } } @@ -31,16 +29,14 @@ class ApplicationContext * A component annotation is used for specifying which factory methods produce components in * an application context. */ -struct Component -{ +struct Component { } /** * This annotation allows you to specify by which super type the component should be registered. This * enables you to use type-qualified alternatives for dependencies. */ -struct RegisterByType(Type) -{ +struct RegisterByType(Type) { Type type; } @@ -48,8 +44,7 @@ struct RegisterByType(Type) * Components with the prototype registration will be scoped as dependencies which will create * new instances every time they are resolved. The factory method will be called repeatedly. */ -struct Prototype -{ +struct Prototype { } /** @@ -59,8 +54,7 @@ struct Prototype * It is mostly used for dependencies which come from an external library or when you don't * want to use annotations to set-up dependencies in your classes. */ -public void registerContext(Context : ApplicationContext)(shared(DependencyContainer) container) -{ +public void registerContext(Context : ApplicationContext)(shared(DependencyContainer) container) { auto context = new Context(); context.registerDependencies(container); context.registerContextComponents(container); @@ -69,33 +63,24 @@ public void registerContext(Context : ApplicationContext)(shared(DependencyConta } public void registerContextComponents(ApplicationContextType : ApplicationContext)( - ApplicationContextType context, shared(DependencyContainer) container) -{ - foreach (memberName; __traits(allMembers, ApplicationContextType)) - { - foreach (overload; __traits(getOverloads, context, memberName)) - { - static if (__traits(getProtection, overload) == "public" && hasUDA!(overload, Component)) - { + ApplicationContextType context, shared(DependencyContainer) container) { + foreach (memberName; __traits(allMembers, ApplicationContextType)) { + foreach (overload; __traits(getOverloads, context, memberName)) { + static if (__traits(getProtection, overload) == "public" && hasUDA!(overload, Component)) { auto factoryMethod = &__traits(getMember, context, memberName); Registration registration = null; auto createsSingleton = CreatesSingleton.yes; - foreach (attribute; __traits(getAttributes, overload)) - { - static if (is(attribute == RegisterByType!T, T)) - { + foreach (attribute; __traits(getAttributes, overload)) { + static if (is(attribute == RegisterByType!T, T)) { registration = container.register!(typeof(attribute.type), ReturnType!factoryMethod); - } - else static if (__traits(isSame, attribute, Prototype)) - { + } else static if (__traits(isSame, attribute, Prototype)) { createsSingleton = CreatesSingleton.no; } } - if (registration is null) - { + if (registration is null) { registration = container.register!(ReturnType!factoryMethod); } diff --git a/source/poodinis/factory.d b/source/poodinis/factory.d index 25d353b..4526a62 100644 --- a/source/poodinis/factory.d +++ b/source/poodinis/factory.d @@ -19,8 +19,7 @@ import std.exception : enforce; import std.traits : Parameters, isBuiltinType, fullyQualifiedName; import std.string : format; -debug -{ +debug { import std.stdio : writeln; } @@ -28,42 +27,34 @@ alias CreatesSingleton = Flag!"CreatesSingleton"; alias InstanceFactoryMethod = Object delegate(); alias InstanceEventHandler = void delegate(Object instance); -class InstanceCreationException : Exception -{ - this(string message, string file = __FILE__, size_t line = __LINE__) - { +class InstanceCreationException : Exception { + this(string message, string file = __FILE__, size_t line = __LINE__) { super(message, file, line); } } -struct InstanceFactoryParameters -{ +struct InstanceFactoryParameters { TypeInfo_Class instanceType; CreatesSingleton createsSingleton = CreatesSingleton.yes; Object existingInstance; InstanceFactoryMethod factoryMethod; } -class InstanceFactory -{ +class InstanceFactory { private Object instance = null; private InstanceFactoryParameters _factoryParameters; private InstanceEventHandler _constructionHandler; - this() - { + this() { factoryParameters = InstanceFactoryParameters(); } - public @property void factoryParameters(InstanceFactoryParameters factoryParameters) - { - if (factoryParameters.factoryMethod is null) - { + public @property void factoryParameters(InstanceFactoryParameters factoryParameters) { + if (factoryParameters.factoryMethod is null) { factoryParameters.factoryMethod = &this.createInstance; } - if (factoryParameters.existingInstance !is null) - { + if (factoryParameters.existingInstance !is null) { factoryParameters.createsSingleton = CreatesSingleton.yes; this.instance = factoryParameters.existingInstance; } @@ -71,99 +62,76 @@ class InstanceFactory _factoryParameters = factoryParameters; } - public @property InstanceFactoryParameters factoryParameters() - { + public @property InstanceFactoryParameters factoryParameters() { return _factoryParameters; } - public Object getInstance() - { - if (_factoryParameters.createsSingleton && instance !is null) - { - debug (poodinisVerbose) - { + public Object getInstance() { + if (_factoryParameters.createsSingleton && instance !is null) { + debug (poodinisVerbose) { printDebugUseExistingInstance(); } return instance; } - debug (poodinisVerbose) - { + debug (poodinisVerbose) { printDebugCreateNewInstance(); } instance = _factoryParameters.factoryMethod(); - if (_constructionHandler !is null) - { + if (_constructionHandler !is null) { _constructionHandler(instance); } return instance; } - void onConstructed(InstanceEventHandler handler) - { + void onConstructed(InstanceEventHandler handler) { _constructionHandler = handler; } - private void printDebugUseExistingInstance() - { - debug - { - if (_factoryParameters.instanceType !is null) - { + private void printDebugUseExistingInstance() { + debug { + if (_factoryParameters.instanceType !is null) { writeln(format("DEBUG: Existing instance returned of type %s", _factoryParameters.instanceType.toString())); - } - else - { + } else { writeln("DEBUG: Existing instance returned from custom factory method"); } } } - private void printDebugCreateNewInstance() - { - debug - { - if (_factoryParameters.instanceType !is null) - { + private void printDebugCreateNewInstance() { + debug { + if (_factoryParameters.instanceType !is null) { writeln(format("DEBUG: Creating new instance of type %s", _factoryParameters.instanceType.toString())); - } - else - { + } else { writeln("DEBUG: Creating new instance from custom factory method"); } } } - protected Object createInstance() - { + protected Object createInstance() { enforce!InstanceCreationException(_factoryParameters.instanceType, - "Instance type is not defined, cannot create instance without knowing its type."); + "Instance type is not defined, cannot create instance without knowing its type."); return _factoryParameters.instanceType.create(); } } -class ConstructorInjectingInstanceFactory(InstanceType) : InstanceFactory -{ +class ConstructorInjectingInstanceFactory(InstanceType) : InstanceFactory { private shared DependencyContainer container; private bool isBeingInjected = false; - this(shared DependencyContainer container) - { + this(shared DependencyContainer container) { this.container = container; } - private static string createArgumentList(Params...)() - { + private static string createArgumentList(Params...)() { string argumentList = ""; - foreach (param; Params) - { - if (argumentList.length > 0) - { + foreach (param; Params) { + if (argumentList.length > 0) { argumentList ~= ","; } @@ -172,23 +140,18 @@ class ConstructorInjectingInstanceFactory(InstanceType) : InstanceFactory return argumentList; } - private static string createImportList(Params...)() - { + private static string createImportList(Params...)() { string importList = ""; - foreach (param; Params) - { + foreach (param; Params) { importList ~= createImportsString!param; } return importList; } - private static bool parametersAreValid(Params...)() - { + private static bool parametersAreValid(Params...)() { bool isValid = true; - foreach (param; Params) - { - if (isBuiltinType!param || is(param == struct)) - { + foreach (param; Params) { + if (isBuiltinType!param || is(param == struct)) { isValid = false; break; } @@ -197,26 +160,23 @@ class ConstructorInjectingInstanceFactory(InstanceType) : InstanceFactory return isValid; } - protected override Object createInstance() - { + protected override Object createInstance() { enforce!InstanceCreationException(container, - "A dependency container is not defined. Cannot perform constructor injection without one."); + "A dependency container is not defined. Cannot perform constructor injection without one."); enforce!InstanceCreationException(!isBeingInjected, - format("%s is already being created and injected; possible circular dependencies in constructors?", - InstanceType.stringof)); + format("%s is already being created and injected; possible circular dependencies in constructors?", + InstanceType.stringof)); Object instance = null; - static if (__traits(compiles, __traits(getOverloads, InstanceType, `__ctor`))) - { - foreach (ctor; __traits(getOverloads, InstanceType, `__ctor`)) - { - static if (parametersAreValid!(Parameters!ctor)) - { + static if (__traits(compiles, __traits(getOverloads, InstanceType, `__ctor`))) { + foreach (ctor; __traits(getOverloads, InstanceType, `__ctor`)) { + static if (parametersAreValid!(Parameters!ctor)) { isBeingInjected = true; mixin(createImportsString!InstanceType ~ createImportList!( Parameters!ctor) ~ ` - instance = new ` ~ fullyQualifiedName!InstanceType ~ `(` ~ createArgumentList!( - Parameters!ctor) ~ `); + instance = new ` + ~ fullyQualifiedName!InstanceType ~ `(` ~ createArgumentList!( + Parameters!ctor) ~ `); `); isBeingInjected = false; break; @@ -224,13 +184,12 @@ class ConstructorInjectingInstanceFactory(InstanceType) : InstanceFactory } } - if (instance is null) - { + if (instance is null) { instance = typeid(InstanceType).create(); } enforce!InstanceCreationException(instance !is null, - "Unable to create instance of type" ~ InstanceType.stringof + "Unable to create instance of type" ~ InstanceType.stringof ~ ", does it have injectable constructors?"); return instance; diff --git a/source/poodinis/imports.d b/source/poodinis/imports.d index be28e92..b2eb3c3 100644 --- a/source/poodinis/imports.d +++ b/source/poodinis/imports.d @@ -14,16 +14,12 @@ module poodinis.imports; import std.meta : staticIndexOf; import std.traits : moduleName, TemplateArgsOf, isBuiltinType, isType; -public static string createImportsString(Type, ParentTypeList...)() -{ +public static string createImportsString(Type, ParentTypeList...)() { string imports = `import ` ~ moduleName!Type ~ `;`; - static if (__traits(compiles, TemplateArgsOf!Type)) - { - foreach (TemplateArgType; TemplateArgsOf!Type) - { + static if (__traits(compiles, TemplateArgsOf!Type)) { + foreach (TemplateArgType; TemplateArgsOf!Type) { static if (isType!TemplateArgType && - (!isBuiltinType!TemplateArgType && staticIndexOf!(TemplateArgType, ParentTypeList) == -1)) - { + (!isBuiltinType!TemplateArgType && staticIndexOf!(TemplateArgType, ParentTypeList) == -1)) { imports ~= createImportsString!(TemplateArgType, ParentTypeList, Type); } } diff --git a/source/poodinis/polyfill.d b/source/poodinis/polyfill.d index 0ca5f2c..c41a6ce 100644 --- a/source/poodinis/polyfill.d +++ b/source/poodinis/polyfill.d @@ -27,10 +27,8 @@ module poodinis.polyfill; import std.exception; -static if (!__traits(compiles, basicExceptionCtors)) -{ - mixin template basicExceptionCtors() - { +static if (!__traits(compiles, basicExceptionCtors)) { + mixin template basicExceptionCtors() { /++ Params: msg = The message for the exception. @@ -38,8 +36,7 @@ static if (!__traits(compiles, basicExceptionCtors)) line = The line number where the exception occurred. next = The previous exception in the chain of exceptions, if any. +/ - this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) @nogc @safe pure nothrow - { + this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) @nogc @safe pure nothrow { super(msg, file, line, next); } @@ -50,13 +47,10 @@ static if (!__traits(compiles, basicExceptionCtors)) file = The file where the exception occurred. line = The line number where the exception occurred. +/ - this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) @nogc @safe pure nothrow - { + this(string msg, Throwable next, string file = __FILE__, size_t line = __LINE__) @nogc @safe pure nothrow { super(msg, file, line, next); } } -} -else -{ +} else { public import std.exception : basicExceptionCtors; } diff --git a/source/poodinis/registration.d b/source/poodinis/registration.d index 91d164c..bc02843 100644 --- a/source/poodinis/registration.d +++ b/source/poodinis/registration.d @@ -17,8 +17,7 @@ import poodinis.container : DependencyContainer; import poodinis.factory : InstanceFactory, InstanceEventHandler, InstanceCreationException, InstanceFactoryParameters, CreatesSingleton; -class Registration -{ +class Registration { private TypeInfo _registeredType = null; private TypeInfo_Class _instanceType = null; private Registration linkedRegistration; @@ -26,82 +25,68 @@ class Registration private InstanceFactory _instanceFactory; private void delegate() _preDestructor; - public @property registeredType() - { + public @property registeredType() { return _registeredType; } - public @property instanceType() - { + public @property instanceType() { return _instanceType; } - public @property originatingContainer() - { + public @property originatingContainer() { return _originatingContainer; } - public @property instanceFactory() - { + public @property instanceFactory() { return _instanceFactory; } - public @property preDestructor() - { + public @property preDestructor() { return _preDestructor; } - protected @property preDestructor(void delegate() preDestructor) - { + protected @property preDestructor(void delegate() preDestructor) { _preDestructor = preDestructor; } this(TypeInfo registeredType, TypeInfo_Class instanceType, - InstanceFactory instanceFactory, shared(DependencyContainer) originatingContainer) - { + InstanceFactory instanceFactory, shared(DependencyContainer) originatingContainer) { this._registeredType = registeredType; this._instanceType = instanceType; this._originatingContainer = originatingContainer; this._instanceFactory = instanceFactory; } - public Object getInstance(InstantiationContext context = new InstantiationContext()) - { - if (linkedRegistration !is null) - { + public Object getInstance(InstantiationContext context = new InstantiationContext()) { + if (linkedRegistration !is null) { return linkedRegistration.getInstance(context); } - if (instanceFactory is null) - { + if (instanceFactory is null) { throw new InstanceCreationException( - "No instance factory defined for registration of type " ~ registeredType.toString()); + "No instance factory defined for registration of type " ~ registeredType.toString()); } return instanceFactory.getInstance(); } - public Registration linkTo(Registration registration) - { + public Registration linkTo(Registration registration) { this.linkedRegistration = registration; return this; } - Registration onConstructed(InstanceEventHandler handler) - { + Registration onConstructed(InstanceEventHandler handler) { if (instanceFactory !is null) instanceFactory.onConstructed(handler); return this; } } -private InstanceFactoryParameters copyFactoryParameters(Registration registration) -{ +private InstanceFactoryParameters copyFactoryParameters(Registration registration) { return registration.instanceFactory.factoryParameters; } -private void setFactoryParameters(Registration registration, InstanceFactoryParameters newParameters) -{ +private void setFactoryParameters(Registration registration, InstanceFactoryParameters newParameters) { registration.instanceFactory.factoryParameters = newParameters; } @@ -110,8 +95,7 @@ private void setFactoryParameters(Registration registration, InstanceFactoryPara * * This is not a registration scope. Typically used by Poodinis internally only. */ -public Registration initializeFactoryType(Registration registration) -{ +public Registration initializeFactoryType(Registration registration) { auto params = registration.copyFactoryParameters(); params.instanceType = registration.instanceType; registration.setFactoryParameters(params); @@ -123,8 +107,7 @@ public Registration initializeFactoryType(Registration registration) * * Effectively makes the given registration a singleton. */ -public Registration singleInstance(Registration registration) -{ +public Registration singleInstance(Registration registration) { auto params = registration.copyFactoryParameters(); params.createsSingleton = CreatesSingleton.yes; registration.setFactoryParameters(params); @@ -134,8 +117,7 @@ public Registration singleInstance(Registration registration) /** * Scopes registrations to return a new instance every time the given registration is resolved. */ -public Registration newInstance(Registration registration) -{ +public Registration newInstance(Registration registration) { auto params = registration.copyFactoryParameters(); params.createsSingleton = CreatesSingleton.no; params.existingInstance = null; @@ -146,8 +128,7 @@ 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) -{ +public Registration existingInstance(Registration registration, Object instance) { auto params = registration.copyFactoryParameters(); params.createsSingleton = CreatesSingleton.yes; params.existingInstance = instance; @@ -159,8 +140,7 @@ public Registration existingInstance(Registration registration, Object instance) * Scopes registrations to create new instances using the given initializer delegate. */ public Registration initializedBy(T)(Registration registration, T delegate() initializer) - if (is(T == class) || is(T == interface)) -{ + if (is(T == class) || is(T == interface)) { auto params = registration.copyFactoryParameters(); params.createsSingleton = CreatesSingleton.no; params.factoryMethod = () => cast(Object) initializer(); @@ -171,8 +151,7 @@ public Registration initializedBy(T)(Registration registration, T delegate() ini /** * 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) -{ +public Registration initializedOnceBy(T : Object)(Registration registration, T delegate() initializer) { auto params = registration.copyFactoryParameters(); params.createsSingleton = CreatesSingleton.yes; params.factoryMethod = () => cast(Object) initializer(); @@ -180,13 +159,10 @@ public Registration initializedOnceBy(T : Object)(Registration registration, T d return registration; } -public string toConcreteTypeListString(Registration[] registrations) -{ +public string toConcreteTypeListString(Registration[] registrations) { auto concreteTypeListString = ""; - foreach (registration; registrations) - { - if (concreteTypeListString.length > 0) - { + foreach (registration; registrations) { + if (concreteTypeListString.length > 0) { concreteTypeListString ~= ", "; } concreteTypeListString ~= registration.instanceType.toString(); @@ -194,6 +170,5 @@ public string toConcreteTypeListString(Registration[] registrations) return concreteTypeListString; } -class InstantiationContext -{ +class InstantiationContext { } diff --git a/source/poodinis/valueinjection.d b/source/poodinis/valueinjection.d index f828ba4..64d7d5f 100644 --- a/source/poodinis/valueinjection.d +++ b/source/poodinis/valueinjection.d @@ -18,23 +18,19 @@ import std.string : format; /** * Thrown when something goes wrong during value injection. */ -class ValueInjectionException : Exception -{ +class ValueInjectionException : Exception { mixin basicExceptionCtors; } /** * Thrown by injectors when the value with the given key cannot be found. */ -class ValueNotAvailableException : Exception -{ - this(string key) - { +class ValueNotAvailableException : Exception { + this(string key) { super(format("Value for key %s is not available", key)); } - this(string key, Throwable cause) - { + this(string key, Throwable cause) { super(format("Value for key %s is not available", key), cause); } } @@ -56,8 +52,7 @@ class ValueNotAvailableException : Exception * } * --- */ -struct Value -{ +struct Value { /** * The textual key used to find the value by injectors. * @@ -83,8 +78,7 @@ struct Value * } * --- */ -struct MandatoryValue -{ +struct MandatoryValue { /** * The textual key used to find the value by injectors. * @@ -115,8 +109,7 @@ struct MandatoryValue * container.register!(ValueInjector!int, MyIntInjector); * --- */ -interface ValueInjector(Type) -{ +interface ValueInjector(Type) { /** * Get a value from the injector by key. * diff --git a/test/poodinis/autowiretest.d b/test/poodinis/autowiretest.d index 4204eb7..dbe5153 100644 --- a/test/poodinis/autowiretest.d +++ b/test/poodinis/autowiretest.d @@ -10,12 +10,10 @@ import poodinis.test.testclasses; import std.exception; -version (unittest) -{ +version (unittest) { // Test autowiring concrete type to existing instance - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ComponentA; auto componentB = new ComponentB(); @@ -24,8 +22,7 @@ version (unittest) } // Test autowiring interface type to existing instance - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(InterfaceA, ComponentC); auto componentD = new ComponentD(); @@ -34,8 +31,7 @@ version (unittest) } // Test autowiring private members - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(InterfaceA, ComponentC); auto componentD = new ComponentD(); @@ -45,8 +41,7 @@ version (unittest) } // Test autowiring will only happen once - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(InterfaceA, ComponentC).newInstance(); auto componentD = new ComponentD(); @@ -59,8 +54,7 @@ version (unittest) } // Test autowiring unregistered type - unittest - { + unittest { auto container = new shared DependencyContainer(); auto componentD = new ComponentD(); assertThrown!(ResolveException)(container.autowire(componentD), @@ -68,8 +62,7 @@ version (unittest) } // Test autowiring member with non-autowire attribute does not autowire - unittest - { + unittest { auto container = new shared DependencyContainer(); auto componentE = new ComponentE(); container.autowire(componentE); @@ -78,8 +71,7 @@ version (unittest) } // Test autowire class with alias declaration - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ComponentA; auto componentDeclarationCocktail = new ComponentDeclarationCocktail(); @@ -91,8 +83,7 @@ version (unittest) } // Test autowire class with qualifier - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(InterfaceA, ComponentC); container.register!(InterfaceA, ComponentX); @@ -105,8 +96,7 @@ version (unittest) } // Test autowire class with multiple qualifiers - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(InterfaceA, ComponentC); container.register!(InterfaceA, ComponentX); @@ -123,8 +113,7 @@ version (unittest) } // Test getting instance from autowired registration will autowire instance - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ComponentA; @@ -137,8 +126,7 @@ version (unittest) } // Test autowiring a dynamic array with all qualified types - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(InterfaceA, ComponentC); container.register!(InterfaceA, ComponentX); @@ -150,8 +138,7 @@ version (unittest) } // Test autowiring new instance of singleinstance registration with newInstance UDA - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ComponentA; @@ -165,8 +152,7 @@ version (unittest) } // Test autowiring members from base class - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ComponentA; container.register!ComponentB; @@ -179,8 +165,7 @@ version (unittest) } // Test autowiring optional dependencies - unittest - { + unittest { auto container = new shared DependencyContainer(); auto instance = new OuttaTime(); @@ -192,8 +177,7 @@ version (unittest) } // Test autowiring class using value injection - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(ValueInjector!int, TestInjector); @@ -207,8 +191,7 @@ version (unittest) } // Test autowiring classes with recursive template parameters - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!CircularTemplateComponentA; container.register!CircularTemplateComponentB; @@ -224,8 +207,7 @@ version (unittest) } // Test autowiring class where a method is marked with @Autowire does nothing - unittest - { + unittest { // It should also not show deprecation warning: // Deprecation: `__traits(getAttributes)` may only be used for individual functions, not overload sets such as: `lala` // the result of `__traits(getOverloads)` may be used to select the desired function to extract attributes from diff --git a/test/poodinis/containertest.d b/test/poodinis/containertest.d index 1938e8b..7546feb 100644 --- a/test/poodinis/containertest.d +++ b/test/poodinis/containertest.d @@ -12,21 +12,18 @@ import poodinis.test.foreigndependencies; import std.exception; import core.thread; -version (unittest) -{ +version (unittest) { // Test register concrete type - unittest - { + unittest { auto container = new shared DependencyContainer(); auto registration = container.register!TestClass; assert(registration.registeredType == typeid(TestClass), - "Type of registered type not the same"); + "Type of registered type not the same"); } // Test resolve registered type - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!TestClass; TestClass actualInstance = container.resolve!TestClass; @@ -35,81 +32,73 @@ version (unittest) } // Test register interface - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(TestInterface, TestClass); TestInterface actualInstance = container.resolve!TestInterface; assert(actualInstance !is null, "Resolved type is null"); assert(cast(TestInterface) actualInstance, - "Resolved class is not the same type as expected"); + "Resolved class is not the same type as expected"); } // Test resolve non-registered type - unittest - { + unittest { auto container = new shared DependencyContainer(); assertThrown!ResolveException(container.resolve!TestClass, - "Resolving non-registered type does not fail"); + "Resolving non-registered type does not fail"); } // Test clear registrations - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!TestClass; container.clearAllRegistrations(); assertThrown!ResolveException(container.resolve!TestClass, - "Resolving cleared type does not fail"); + "Resolving cleared type does not fail"); } // Test resolve single instance for type - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!TestClass.singleInstance(); auto instance1 = container.resolve!TestClass; auto instance2 = container.resolve!TestClass; assert(instance1 is instance2, - "Resolved instance from single instance scope is not the each time it is resolved"); + "Resolved instance from single instance scope is not the each time it is resolved"); } // Test resolve new instance for type - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!TestClass.newInstance(); auto instance1 = container.resolve!TestClass; auto instance2 = container.resolve!TestClass; assert(instance1 !is instance2, - "Resolved instance from new instance scope is the same each time it is resolved"); + "Resolved instance from new instance scope is the same each time it is resolved"); } // Test resolve existing instance for type - unittest - { + unittest { auto container = new shared DependencyContainer(); auto expectedInstance = new TestClass(); container.register!TestClass.existingInstance(expectedInstance); auto actualInstance = container.resolve!TestClass; assert(expectedInstance is actualInstance, - "Resolved instance from existing instance scope is not the same as the registered instance"); + "Resolved instance from existing instance scope is not the same as the registered instance"); } // Test creating instance via custom initializer on resolve - unittest - { + unittest { auto container = new shared DependencyContainer(); auto expectedInstance = new TestClass(); container.register!TestClass.initializedBy({ return expectedInstance; }); auto actualInstance = container.resolve!TestClass; assert(expectedInstance is actualInstance, - "Resolved instance does not come from the custom initializer"); + "Resolved instance does not come from the custom initializer"); } // Test creating instance via initializedBy creates new instance every time - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!TestClass.initializedBy({ return new TestClass(); }); auto firstInstance = container.resolve!TestClass; @@ -118,8 +107,7 @@ version (unittest) } // Test creating instance via initializedOnceBy creates a singleton instance - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!TestClass.initializedOnceBy({ return new TestClass(); }); auto firstInstance = container.resolve!TestClass; @@ -128,32 +116,29 @@ version (unittest) } // Test autowire resolved instances - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!AutowiredClass; container.register!ComponentClass; auto componentInstance = container.resolve!ComponentClass; auto autowiredInstance = container.resolve!AutowiredClass; assert(componentInstance.autowiredClass is autowiredInstance, - "Member is not autowired upon resolving"); + "Member is not autowired upon resolving"); } // Test circular autowiring - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ComponentMouse; container.register!ComponentCat; auto mouse = container.resolve!ComponentMouse; auto cat = container.resolve!ComponentCat; assert(mouse.cat is cat && cat.mouse is mouse && mouse !is cat, - "Circular dependencies should be autowirable"); + "Circular dependencies should be autowirable"); } // Test remove registration - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!TestClass; container.removeRegistration!TestClass; @@ -161,8 +146,7 @@ version (unittest) } // Test autowiring does not autowire member where instance is non-null - unittest - { + unittest { auto container = new shared DependencyContainer(); auto existingA = new AutowiredClass(); auto existingB = new ComponentClass(); @@ -174,12 +158,11 @@ version (unittest) auto resolvedB = container.resolve!ComponentClass; assert(resolvedB.autowiredClass is existingA && resolvedA !is existingA, - "Autowiring shouldn't rewire member when it is already wired to an instance"); + "Autowiring shouldn't rewire member when it is already wired to an instance"); } // Test autowiring circular dependency by third-degree - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Eenie; container.register!Meenie; @@ -188,12 +171,11 @@ version (unittest) auto eenie = container.resolve!Eenie; assert(eenie.meenie.moe.eenie is eenie, - "Autowiring third-degree circular dependency failed"); + "Autowiring third-degree circular dependency failed"); } // Test autowiring deep circular dependencies - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Ittie; container.register!Bittie; @@ -205,8 +187,7 @@ version (unittest) } // Test autowiring deep circular dependencies with newInstance scope does not autowire new instance second time - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Ittie.newInstance(); container.register!Bittie.newInstance(); @@ -215,12 +196,11 @@ version (unittest) auto ittie = container.resolve!Ittie; assert(ittie.bittie.banana.bittie.banana is null, - "Autowiring deep dependencies with newInstance scope autowired a reoccuring type."); + "Autowiring deep dependencies with newInstance scope autowired a reoccuring type."); } // Test autowiring type registered by interface - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Bunena; container.register!Bittie; @@ -230,21 +210,17 @@ version (unittest) .resolve!SuperInterface; assert(!(superInstance.banana is null), - "Instance which was resolved by interface type was not autowired."); + "Instance which was resolved by interface type was not autowired."); } // Test reusing a container after clearing all registrations - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Banana; container.clearAllRegistrations(); - try - { + try { container.resolve!Banana; - } - catch (ResolveException e) - { + } catch (ResolveException e) { container.register!Banana; return; } @@ -252,16 +228,14 @@ version (unittest) } // Test register multiple concrete classess to same interface type - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(Color, Blue); container.register!(Color, Red); } // Test removing all registrations for type with multiple registrations. - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(Color, Blue); container.register!(Color, Red); @@ -269,36 +243,30 @@ version (unittest) } // Test registering same registration again - unittest - { + unittest { auto container = new shared DependencyContainer(); auto firstRegistration = container.register!(Color, Blue); auto secondRegistration = container.register!(Color, Blue); assert(firstRegistration is secondRegistration, - "First registration is not the same as the second of equal types"); + "First registration is not the same as the second of equal types"); } // Test resolve registration with multiple qualifiers - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(Color, Blue); container.register!(Color, Red); - try - { + try { container.resolve!Color; - } - catch (ResolveException e) - { + } catch (ResolveException e) { return; } assert(false); } // Test resolve registration with multiple qualifiers using a qualifier - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(Color, Blue); container.register!(Color, Red); @@ -306,14 +274,13 @@ version (unittest) auto redInstance = container.resolve!(Color, Red); assert(blueInstance !is redInstance, - "Resolving type with multiple, different registrations yielded the same instance"); + "Resolving type with multiple, different registrations yielded the same instance"); assert(blueInstance !is null, "Resolved blue instance to null"); assert(redInstance !is null, "Resolved red instance to null"); } // Test autowire of unqualified member typed by interface. - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Spiders; container.register!(TestInterface, TestClass); @@ -324,32 +291,29 @@ version (unittest) } // Register existing registration - unittest - { + unittest { auto container = new shared DependencyContainer(); auto firstRegistration = container.register!TestClass; auto secondRegistration = container.register!TestClass; assert(firstRegistration is secondRegistration, - "Registering the same registration twice registers the dependencies twice."); + "Registering the same registration twice registers the dependencies twice."); } // Register existing registration by supertype - unittest - { + unittest { auto container = new shared DependencyContainer(); auto firstRegistration = container.register!(TestInterface, TestClass); auto secondRegistration = container.register!(TestInterface, TestClass); assert(firstRegistration is secondRegistration, - "Registering the same registration by super type twice registers the dependencies twice."); + "Registering the same registration by super type twice registers the dependencies twice."); } // Resolve dependency depending on itself - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Recursive; @@ -357,12 +321,11 @@ version (unittest) assert(instance.recursive is instance, "Resolving dependency that depends on itself fails."); assert(instance.recursive.recursive is instance, - "Resolving dependency that depends on itself fails."); + "Resolving dependency that depends on itself fails."); } // Test autowire stack pop-back - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Moolah; container.register!Wants.newInstance(); @@ -375,8 +338,7 @@ version (unittest) } // Test resolving registration registered in different thread - unittest - { + unittest { auto container = new shared DependencyContainer(); auto thread = new Thread(delegate() { container.register!TestClass; }); @@ -387,8 +349,7 @@ version (unittest) } // Test resolving instance previously resolved in different thread - unittest - { + unittest { auto container = new shared DependencyContainer(); shared(TestClass) actualTestClass; @@ -403,31 +364,28 @@ version (unittest) shared(TestClass) expectedTestClass = cast(shared(TestClass)) container.resolve!TestClass; assert(expectedTestClass is actualTestClass, - "Instance resolved in main thread is not the one resolved in thread"); + "Instance resolved in main thread is not the one resolved in thread"); } // Test registering type with option doNotAddConcreteTypeRegistration - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(TestInterface, - TestClass)(RegistrationOption.doNotAddConcreteTypeRegistration); + TestClass)(RegistrationOption.doNotAddConcreteTypeRegistration); auto firstInstance = container.resolve!TestInterface; assertThrown!ResolveException(container.resolve!TestClass); } // Test registering conrete type with registration option doNotAddConcreteTypeRegistration does nothing - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!TestClass(RegistrationOption.doNotAddConcreteTypeRegistration); container.resolve!TestClass; } // Test registering type will register by contrete type by default - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(TestInterface, TestClass); @@ -438,8 +396,7 @@ version (unittest) } // Test resolving all registrations to an interface - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(Color, Blue); container.register!(Color, Red); @@ -450,8 +407,7 @@ version (unittest) } // Test autowiring instances resolved in array - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!UnrelatedClass; container.register!(TestInterface, TestClassDeux); @@ -463,45 +419,40 @@ version (unittest) } // Test set persistent registration options - unittest - { + unittest { auto container = new shared DependencyContainer(); container.setPersistentRegistrationOptions( - RegistrationOption.doNotAddConcreteTypeRegistration); + RegistrationOption.doNotAddConcreteTypeRegistration); container.register!(TestInterface, TestClass); assertThrown!ResolveException(container.resolve!TestClass); } // Test unset persistent registration options - unittest - { + unittest { auto container = new shared DependencyContainer(); container.setPersistentRegistrationOptions( - RegistrationOption.doNotAddConcreteTypeRegistration); + RegistrationOption.doNotAddConcreteTypeRegistration); container.unsetPersistentRegistrationOptions(); container.register!(TestInterface, TestClass); container.resolve!TestClass; } // Test registration when resolving - unittest - { + unittest { auto container = new shared DependencyContainer(); container.resolve!(TestInterface, TestClass)(ResolveOption.registerBeforeResolving); container.resolve!TestClass; } // Test set persistent resolve options - unittest - { + unittest { auto container = new shared DependencyContainer(); container.setPersistentResolveOptions(ResolveOption.registerBeforeResolving); container.resolve!TestClass; } // Test unset persistent resolve options - unittest - { + unittest { auto container = new shared DependencyContainer(); container.setPersistentResolveOptions(ResolveOption.registerBeforeResolving); container.unsetPersistentResolveOptions(); @@ -509,32 +460,28 @@ version (unittest) } // Test ResolveOption registerBeforeResolving fails for interfaces - unittest - { + unittest { auto container = new shared DependencyContainer(); assertThrown!ResolveException( - container.resolve!TestInterface(ResolveOption.registerBeforeResolving)); + container.resolve!TestInterface(ResolveOption.registerBeforeResolving)); } // Test ResolveOption noResolveException does not throw - unittest - { + unittest { auto container = new shared DependencyContainer(); auto instance = container.resolve!TestInterface(ResolveOption.noResolveException); assert(instance is null); } // ResolveOption noResolveException does not throw for resolveAll - unittest - { + unittest { auto container = new shared DependencyContainer(); auto instances = container.resolveAll!TestInterface(ResolveOption.noResolveException); assert(instances.length == 0); } // Test autowired, constructor injected class - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Red; container.register!Moolah; @@ -548,8 +495,7 @@ version (unittest) } // Test autowired, constructor injected class where constructor argument is templated - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!PieChart; container.register!(TemplatedComponent!PieChart); @@ -562,8 +508,7 @@ version (unittest) } // Test injecting constructor with super-type parameter - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Wallpaper; container.register!(Color, Blue); @@ -574,8 +519,7 @@ version (unittest) } // Test prevention of circular dependencies during constructor injection - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Pot; container.register!Kettle; @@ -584,8 +528,7 @@ version (unittest) } // Test prevention of transitive circular dependencies during constructor injection - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Rock; container.register!Paper; @@ -595,8 +538,7 @@ version (unittest) } // Test injection of foreign dependency in constructor - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Ola; container.register!Hello; @@ -604,8 +546,7 @@ version (unittest) } // Test PostConstruct method is called after resolving a dependency - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!PostConstructionDependency; @@ -614,8 +555,7 @@ version (unittest) } // Test PostConstruct of base type is called - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ChildOfPostConstruction; @@ -624,8 +564,7 @@ version (unittest) } // Test PostConstruct of class implementing interface is not called - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ButThereWontBe; @@ -634,8 +573,7 @@ version (unittest) } // Test postconstruction happens after autowiring and value injection - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(ValueInjector!int, PostConstructingIntInjector); container.register!PostConstructionDependency; @@ -644,8 +582,7 @@ version (unittest) } // Test PreDestroy is called when removing a registration - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!PreDestroyerOfFates; auto instance = container.resolve!PreDestroyerOfFates; @@ -654,8 +591,7 @@ version (unittest) } // Test PreDestroy is called when removing all registrations - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!PreDestroyerOfFates; auto instance = container.resolve!PreDestroyerOfFates; @@ -664,8 +600,7 @@ version (unittest) } // Test PreDestroy is called when the container is destroyed - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!PreDestroyerOfFates; auto instance = container.resolve!PreDestroyerOfFates; @@ -675,8 +610,7 @@ version (unittest) } // Test register class by ancestor type - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(Grandma, Kid); auto instance = container.resolve!Grandma; diff --git a/test/poodinis/contexttest.d b/test/poodinis/contexttest.d index 72d703a..d35b229 100644 --- a/test/poodinis/contexttest.d +++ b/test/poodinis/contexttest.d @@ -10,12 +10,10 @@ import poodinis.test.testclasses; import std.exception; -version (unittest) -{ +version (unittest) { //Test register component registrations from context - unittest - { + unittest { auto container = new shared DependencyContainer(); auto context = new TestContext(); context.registerContextComponents(container); @@ -25,8 +23,7 @@ version (unittest) } //Test non-annotated methods are not registered - unittest - { + unittest { auto container = new shared DependencyContainer(); auto context = new TestContext(); context.registerContextComponents(container); @@ -34,8 +31,7 @@ version (unittest) } //Test register component by base type - unittest - { + unittest { auto container = new shared DependencyContainer(); auto context = new TestContext(); context.registerContextComponents(container); @@ -44,8 +40,7 @@ version (unittest) } //Test register components with multiple candidates - unittest - { + unittest { auto container = new shared DependencyContainer(); auto context = new TestContext(); context.registerContextComponents(container); @@ -58,8 +53,7 @@ version (unittest) } //Test register component as prototype - unittest - { + unittest { auto container = new shared DependencyContainer(); auto context = new TestContext(); context.registerContextComponents(container); @@ -72,8 +66,7 @@ version (unittest) } // Test setting up simple dependencies through application context - unittest - { + unittest { auto container = new shared DependencyContainer(); container.registerContext!SimpleContext; auto instance = container.resolve!CakeChart; @@ -82,8 +75,7 @@ version (unittest) } // Test resolving dependency from registered application context - unittest - { + unittest { auto container = new shared DependencyContainer(); container.registerContext!SimpleContext; auto instance = container.resolve!Apple; @@ -92,8 +84,7 @@ version (unittest) } // Test autowiring application context - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!Apple; container.registerContext!AutowiredTestContext; @@ -104,8 +95,7 @@ version (unittest) } // Test autowiring application context with dependencies registered in same context - unittest - { + unittest { auto container = new shared DependencyContainer(); container.registerContext!ComplexAutowiredTestContext; auto instance = container.resolve!ClassWrapperWrapper; @@ -118,8 +108,7 @@ version (unittest) } // Test resolving registered context - unittest - { + unittest { auto container = new shared DependencyContainer(); container.registerContext!TestContext; container.resolve!ApplicationContext; diff --git a/test/poodinis/factorytest.d b/test/poodinis/factorytest.d index 0a5d03e..ec4dff5 100644 --- a/test/poodinis/factorytest.d +++ b/test/poodinis/factorytest.d @@ -10,15 +10,13 @@ import poodinis.test.testclasses; import std.exception; -version (unittest) -{ +version (unittest) { // Test instance factory with singletons - unittest - { + unittest { auto factory = new InstanceFactory(); factory.factoryParameters = InstanceFactoryParameters(typeid(TestImplementation), - CreatesSingleton.yes); + CreatesSingleton.yes); auto instanceOne = factory.getInstance(); auto instanceTwo = factory.getInstance(); @@ -27,11 +25,10 @@ version (unittest) } // Test instance factory with new instances - unittest - { + unittest { auto factory = new InstanceFactory(); factory.factoryParameters = InstanceFactoryParameters(typeid(TestImplementation), - CreatesSingleton.no); + CreatesSingleton.no); auto instanceOne = factory.getInstance(); auto instanceTwo = factory.getInstance(); @@ -40,39 +37,35 @@ version (unittest) } // Test instance factory with existing instances - unittest - { + unittest { auto existingInstance = new TestImplementation(); auto factory = new InstanceFactory(); factory.factoryParameters = InstanceFactoryParameters(typeid(TestImplementation), - CreatesSingleton.yes, existingInstance); + CreatesSingleton.yes, existingInstance); auto instanceOne = factory.getInstance(); auto instanceTwo = factory.getInstance(); assert(instanceOne is existingInstance, - "Created factory instance is not the existing instance"); + "Created factory instance is not the existing instance"); assert(instanceTwo is existingInstance, - "Created factory instance is not the existing instance when called again"); + "Created factory instance is not the existing instance when called again"); } // Test instance factory with existing instances when setting singleton flag to "no" - unittest - { + unittest { auto existingInstance = new TestImplementation(); auto factory = new InstanceFactory(); factory.factoryParameters = InstanceFactoryParameters(typeid(TestImplementation), - CreatesSingleton.no, existingInstance); + CreatesSingleton.no, existingInstance); auto instance = factory.getInstance(); assert(instance is existingInstance, - "Created factory instance is not the existing instance"); + "Created factory instance is not the existing instance"); } // Test creating instance using custom factory method - unittest - { - Object factoryMethod() - { + unittest { + Object factoryMethod() { auto instance = new TestImplementation(); instance.someContent = "Ducks!"; return instance; @@ -80,17 +73,16 @@ version (unittest) auto factory = new InstanceFactory(); factory.factoryParameters = InstanceFactoryParameters(null, - CreatesSingleton.yes, null, &factoryMethod); + 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"); + "No instance was created by factory or could not be cast to expected type"); assert(instance.someContent == "Ducks!"); } // Test injecting constructor of class - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!TestImplementation; @@ -102,14 +94,13 @@ version (unittest) } // Test injecting constructor of class with multiple constructors injects the first candidate - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!SomeOtherClassThen; container.register!TestImplementation; auto factory = new ConstructorInjectingInstanceFactory!ClassWithMultipleConstructors( - container); + container); auto instance = cast(ClassWithMultipleConstructors) factory.getInstance(); assert(instance !is null); @@ -118,14 +109,13 @@ version (unittest) } // Test injecting constructor of class with multiple constructor parameters - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!SomeOtherClassThen; container.register!TestImplementation; auto factory = new ConstructorInjectingInstanceFactory!ClassWithConstructorWithMultipleParameters( - container); + container); auto instance = cast(ClassWithConstructorWithMultipleParameters) factory.getInstance(); assert(instance !is null); @@ -134,13 +124,12 @@ version (unittest) } // Test injecting constructor of class with primitive constructor parameters - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!SomeOtherClassThen; auto factory = new ConstructorInjectingInstanceFactory!ClassWithPrimitiveConstructor( - container); + container); auto instance = cast(ClassWithPrimitiveConstructor) factory.getInstance(); assert(instance !is null); @@ -148,8 +137,7 @@ version (unittest) } // Test injecting constructor of class with struct constructor parameters - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!SomeOtherClassThen; @@ -161,8 +149,7 @@ version (unittest) } // Test injecting constructor of class with empty constructor will skip injection - unittest - { + unittest { auto container = new shared DependencyContainer(); auto factory = new ConstructorInjectingInstanceFactory!ClassWithEmptyConstructor(container); @@ -173,12 +160,11 @@ version (unittest) } // Test injecting constructor of class with no candidates fails - unittest - { + unittest { auto container = new shared DependencyContainer(); auto factory = new ConstructorInjectingInstanceFactory!ClassWithNonInjectableConstructor( - container); + container); assertThrown!InstanceCreationException(factory.getInstance()); } diff --git a/test/poodinis/foreigndependencies.d b/test/poodinis/foreigndependencies.d index 87f3ca3..abf908a 100644 --- a/test/poodinis/foreigndependencies.d +++ b/test/poodinis/foreigndependencies.d @@ -7,9 +7,7 @@ module poodinis.test.foreigndependencies; -version (unittest) -{ - class Ola - { +version (unittest) { + class Ola { } } diff --git a/test/poodinis/registrationtest.d b/test/poodinis/registrationtest.d index 4984d28..cd07d3b 100644 --- a/test/poodinis/registrationtest.d +++ b/test/poodinis/registrationtest.d @@ -10,65 +10,59 @@ import poodinis.test.testclasses; import std.exception; -version (unittest) -{ +version (unittest) { // Test getting instance without scope defined throws exception - unittest - { + unittest { Registration registration = new Registration(typeid(TestType), null, null, null); assertThrown!(InstanceCreationException)(registration.getInstance(), null); } // Test set single instance scope using scope setter - unittest - { + unittest { Registration registration = new Registration(null, typeid(TestType), - new InstanceFactory(), null).initializeFactoryType(); + new InstanceFactory(), null).initializeFactoryType(); auto chainedRegistration = registration.singleInstance(); auto instance1 = registration.getInstance(); auto instance2 = registration.getInstance(); assert(instance1 is instance2, - "Registration with single instance scope did not return the same instance"); + "Registration with single instance scope did not return the same instance"); assert(registration is chainedRegistration, - "Registration returned by scope setting is not the same as the registration being set"); + "Registration returned by scope setting is not the same as the registration being set"); } // Test set new instance scope using scope setter - unittest - { + unittest { Registration registration = new Registration(null, typeid(TestType), - new InstanceFactory(), null).initializeFactoryType(); + new InstanceFactory(), null).initializeFactoryType(); auto chainedRegistration = registration.newInstance(); auto instance1 = registration.getInstance(); auto instance2 = registration.getInstance(); assert(instance1 !is instance2, - "Registration with new instance scope did not return a different instance"); + "Registration with new instance scope did not return a different instance"); assert(registration is chainedRegistration, - "Registration returned by scope setting is not the same as the registration being set"); + "Registration returned by scope setting is not the same as the registration being set"); } // Test set existing instance scope using scope setter - unittest - { + unittest { Registration registration = new Registration(null, null, new InstanceFactory(), null); auto expectedInstance = new TestType(); auto chainedRegistration = registration.existingInstance(expectedInstance); auto actualInstance = registration.getInstance(); assert(expectedInstance is actualInstance, - "Registration with existing instance scope did not return the same instance"); + "Registration with existing instance scope did not return the same instance"); assert(registration is chainedRegistration, - "Registration returned by scope setting is not the same as the registration being set"); + "Registration returned by scope setting is not the same as the registration being set"); } // Test linking registrations - unittest - { + unittest { Registration firstRegistration = new Registration(typeid(TestInterface), - typeid(TestImplementation), new InstanceFactory(), null).initializeFactoryType() + typeid(TestImplementation), new InstanceFactory(), null).initializeFactoryType() .singleInstance(); Registration secondRegistration = new Registration(typeid(TestImplementation), - typeid(TestImplementation), new InstanceFactory(), null).initializeFactoryType() + typeid(TestImplementation), new InstanceFactory(), null).initializeFactoryType() .singleInstance().linkTo(firstRegistration); auto firstInstance = firstRegistration.getInstance(); @@ -78,10 +72,9 @@ version (unittest) } // Test custom factory method via initializedBy - unittest - { + unittest { Registration registration = new Registration(typeid(TestInterface), - typeid(TestImplementation), new InstanceFactory(), null); + typeid(TestImplementation), new InstanceFactory(), null); registration.initializedBy({ auto instance = new TestImplementation(); @@ -97,10 +90,9 @@ version (unittest) } // Test custom factory method via initializedOnceBy - unittest - { + unittest { Registration registration = new Registration(typeid(TestInterface), - typeid(TestImplementation), new InstanceFactory(), null); + typeid(TestImplementation), new InstanceFactory(), null); registration.initializedOnceBy({ auto instance = new TestImplementation(); @@ -116,10 +108,9 @@ version (unittest) } // Test chaining single/new instance scope to initializedBy will not overwrite the factory method. - unittest - { + unittest { Registration registration = new Registration(typeid(TestInterface), - typeid(TestImplementation), new InstanceFactory(), null); + typeid(TestImplementation), new InstanceFactory(), null); registration.initializedBy({ auto instance = new TestImplementation(); diff --git a/test/poodinis/testclasses.d b/test/poodinis/testclasses.d index b9fbc50..4790c9c 100644 --- a/test/poodinis/testclasses.d +++ b/test/poodinis/testclasses.d @@ -10,92 +10,73 @@ module poodinis.test.testclasses; import poodinis; import poodinis.test.foreigndependencies; -version (unittest) -{ - class ComponentA - { +version (unittest) { + class ComponentA { } - class ComponentB - { + class ComponentB { public @Autowire ComponentA componentA; } - interface InterfaceA - { + interface InterfaceA { } - class ComponentC : InterfaceA - { + class ComponentC : InterfaceA { } - class ComponentD - { + class ComponentD { public @Autowire InterfaceA componentC = null; private @Autowire InterfaceA _privateComponentC = null; - public InterfaceA privateComponentC() - { + public InterfaceA privateComponentC() { return _privateComponentC; } } - class DummyAttribute - { + class DummyAttribute { }; - class ComponentE - { + class ComponentE { @DummyAttribute public ComponentC componentC; } - class ComponentDeclarationCocktail - { + class ComponentDeclarationCocktail { alias noomer = int; @Autowire public ComponentA componentA; - public void doesNothing() - { + public void doesNothing() { } - ~this() - { + ~this() { } } - class ComponentX : InterfaceA - { + class ComponentX : InterfaceA { } - class ComponentZ : ComponentB - { + class ComponentZ : ComponentB { } - class MonkeyShine - { + class MonkeyShine { @Autowire!ComponentX public InterfaceA component; } - class BootstrapBootstrap - { + class BootstrapBootstrap { @Autowire!ComponentX public InterfaceA componentX; @Autowire!ComponentC public InterfaceA componentC; } - class LordOfTheComponents - { + class LordOfTheComponents { @Autowire public InterfaceA[] components; } - class ComponentCharlie - { + class ComponentCharlie { @Autowire @AssignNewInstance public ComponentA componentA; } - class OuttaTime - { + class OuttaTime { @Autowire @OptionalDependency public InterfaceA interfaceA; @Autowire @OptionalDependency public ComponentA componentA; @@ -103,537 +84,423 @@ version (unittest) @Autowire @OptionalDependency public ComponentC[] componentCs; } - class ValuedClass - { + class ValuedClass { @Value("values.int") public int intValue; @Autowire public ComponentA unrelated; } - class TestInjector : ValueInjector!int - { - public override int get(string key) - { + class TestInjector : ValueInjector!int { + public override int get(string key) { assert(key == "values.int"); return 8; } } - interface TestInterface - { + interface TestInterface { } - class TestClass : TestInterface - { + class TestClass : TestInterface { } - class TestClassDeux : TestInterface - { + class TestClassDeux : TestInterface { @Autowire public UnrelatedClass unrelated; } - class UnrelatedClass - { + class UnrelatedClass { } - class FailOnCreationClass - { - this() - { + class FailOnCreationClass { + this() { throw new Exception("This class should not be instantiated"); } } - class AutowiredClass - { + class AutowiredClass { } - class ComponentClass - { + class ComponentClass { @Autowire public AutowiredClass autowiredClass; } - class ComponentCat - { + class ComponentCat { @Autowire public ComponentMouse mouse; } - class ComponentMouse - { + class ComponentMouse { @Autowire public ComponentCat cat; } - class Eenie - { + class Eenie { @Autowire public Meenie meenie; } - class Meenie - { + class Meenie { @Autowire public Moe moe; } - class Moe - { + class Moe { @Autowire public Eenie eenie; } - class Ittie - { + class Ittie { @Autowire public Bittie bittie; } - class Bittie - { + class Bittie { @Autowire public Bunena banana; } - class Bunena - { + class Bunena { @Autowire public Bittie bittie; } - interface SuperInterface - { + interface SuperInterface { } - class SuperImplementation : SuperInterface - { + class SuperImplementation : SuperInterface { @Autowire public Bunena banana; } - interface Color - { + interface Color { } - class Blue : Color - { + class Blue : Color { } - class Red : Color - { + class Red : Color { } - class Spiders - { + class Spiders { @Autowire public TestInterface testMember; } - class Recursive - { + class Recursive { @Autowire public Recursive recursive; } - class Moolah - { + class Moolah { } - class Wants - { + class Wants { @Autowire public Moolah moolah; } - class John - { + class John { @Autowire public Wants wants; } - class Cocktail - { + class Cocktail { @Autowire public Moolah moolah; public Red red; - this(Red red) - { + this(Red red) { this.red = red; } } - class Wallpaper - { + class Wallpaper { public Color color; - this(Color color) - { + this(Color color) { this.color = color; } } - class Pot - { - this(Kettle kettle) - { + class Pot { + this(Kettle kettle) { } } - class Kettle - { - this(Pot pot) - { + class Kettle { + this(Pot pot) { } } - class Rock - { - this(Scissors scissors) - { + class Rock { + this(Scissors scissors) { } } - class Paper - { - this(Rock rock) - { + class Paper { + this(Rock rock) { } } - class Scissors - { - this(Paper paper) - { + class Scissors { + this(Paper paper) { } } - class Hello - { - this(Ola ola) - { + class Hello { + this(Ola ola) { } } - class PostConstructionDependency - { + class PostConstructionDependency { public bool postConstructWasCalled = false; - @PostConstruct public void callMeMaybe() - { + @PostConstruct public void callMeMaybe() { postConstructWasCalled = true; } } - class ChildOfPostConstruction : PostConstructionDependency - { + class ChildOfPostConstruction : PostConstructionDependency { } - interface ThereWillBePostConstruction - { + interface ThereWillBePostConstruction { @PostConstruct void constructIt(); } - class ButThereWontBe : ThereWillBePostConstruction - { + class ButThereWontBe : ThereWillBePostConstruction { public bool postConstructWasCalled = false; - public override void constructIt() - { + public override void constructIt() { postConstructWasCalled = true; } } - class PostConstructWithAutowiring - { + class PostConstructWithAutowiring { @Autowire private PostConstructionDependency dependency; @Value("") private int theNumber = 1; - @PostConstruct public void doIt() - { + @PostConstruct public void doIt() { assert(theNumber == 8783); assert(dependency !is null); } } - class PreDestroyerOfFates - { + class PreDestroyerOfFates { public bool preDestroyWasCalled = false; - @PreDestroy public void callMeMaybe() - { + @PreDestroy public void callMeMaybe() { preDestroyWasCalled = true; } } - class PostConstructingIntInjector : ValueInjector!int - { - int get(string key) - { + class PostConstructingIntInjector : ValueInjector!int { + int get(string key) { return 8783; } } - interface Fruit - { + interface Fruit { string getShape(); } - interface Animal - { + interface Animal { string getYell(); } - class Banana - { + class Banana { public string color; - this(string color) - { + this(string color) { this.color = color; } } - class Apple - { + class Apple { } - class Pear : Fruit - { - public override string getShape() - { + class Pear : Fruit { + public override string getShape() { return "Pear shaped"; } } - class Rabbit : Animal - { - public override string getYell() - { + class Rabbit : Animal { + public override string getYell() { return "Squeeeeeel"; } } - class Wolf : Animal - { - public override string getYell() - { + class Wolf : Animal { + public override string getYell() { return "Wooooooooooo"; } } - class PieChart - { + class PieChart { } - class CakeChart : PieChart - { + class CakeChart : PieChart { } - class ClassWrapper - { + class ClassWrapper { public Object someClass; - this(Object someClass) - { + this(Object someClass) { this.someClass = someClass; } } - class ClassWrapperWrapper - { + class ClassWrapperWrapper { public ClassWrapper wrapper; - this(ClassWrapper wrapper) - { + this(ClassWrapper wrapper) { this.wrapper = wrapper; } } - class SimpleContext : ApplicationContext - { - public override void registerDependencies(shared(DependencyContainer) container) - { + class SimpleContext : ApplicationContext { + public override void registerDependencies(shared(DependencyContainer) container) { container.register!CakeChart; } - @Component public Apple apple() - { + @Component public Apple apple() { return new Apple(); } } - class ComplexAutowiredTestContext : ApplicationContext - { + class ComplexAutowiredTestContext : ApplicationContext { @Autowire private Apple apple; @Autowire protected ClassWrapper classWrapper; - public override void registerDependencies(shared(DependencyContainer) container) - { + public override void registerDependencies(shared(DependencyContainer) container) { container.register!Apple; } - @Component public ClassWrapper wrapper() - { + @Component public ClassWrapper wrapper() { return new ClassWrapper(apple); } - @Component public ClassWrapperWrapper wrapperWrapper() - { + @Component public ClassWrapperWrapper wrapperWrapper() { return new ClassWrapperWrapper(classWrapper); } } - class AutowiredTestContext : ApplicationContext - { + class AutowiredTestContext : ApplicationContext { @Autowire private Apple apple; - @Component public ClassWrapper wrapper() - { + @Component public ClassWrapper wrapper() { return new ClassWrapper(apple); } } - class TestContext : ApplicationContext - { + class TestContext : ApplicationContext { - @Component public Banana banana() - { + @Component public Banana banana() { return new Banana("Yellow"); } - public Apple apple() - { + public Apple apple() { return new Apple(); } - @Component @RegisterByType!Fruit public Pear pear() - { + @Component @RegisterByType!Fruit public Pear pear() { return new Pear(); } - @Component @RegisterByType!Animal public Rabbit rabbit() - { + @Component @RegisterByType!Animal public Rabbit rabbit() { return new Rabbit(); } - @Component @RegisterByType!Animal public Wolf wolf() - { + @Component @RegisterByType!Animal public Wolf wolf() { return new Wolf(); } - @Component @Prototype public PieChart pieChart() - { + @Component @Prototype public PieChart pieChart() { return new PieChart(); } } - class TestImplementation : TestInterface - { + class TestImplementation : TestInterface { public string someContent = ""; } - class SomeOtherClassThen - { + class SomeOtherClassThen { } - class ClassWithConstructor - { + class ClassWithConstructor { public TestImplementation testImplementation; - this(TestImplementation testImplementation) - { + this(TestImplementation testImplementation) { this.testImplementation = testImplementation; } } - class ClassWithMultipleConstructors - { + class ClassWithMultipleConstructors { public SomeOtherClassThen someOtherClassThen; public TestImplementation testImplementation; - this(SomeOtherClassThen someOtherClassThen) - { + this(SomeOtherClassThen someOtherClassThen) { this.someOtherClassThen = someOtherClassThen; } - this(SomeOtherClassThen someOtherClassThen, TestImplementation testImplementation) - { + this(SomeOtherClassThen someOtherClassThen, TestImplementation testImplementation) { this.someOtherClassThen = someOtherClassThen; this.testImplementation = testImplementation; } } - class ClassWithConstructorWithMultipleParameters - { + class ClassWithConstructorWithMultipleParameters { public SomeOtherClassThen someOtherClassThen; public TestImplementation testImplementation; - this(SomeOtherClassThen someOtherClassThen, TestImplementation testImplementation) - { + this(SomeOtherClassThen someOtherClassThen, TestImplementation testImplementation) { this.someOtherClassThen = someOtherClassThen; this.testImplementation = testImplementation; } } - class ClassWithPrimitiveConstructor - { + class ClassWithPrimitiveConstructor { public SomeOtherClassThen someOtherClassThen; - this(string willNotBePicked) - { + this(string willNotBePicked) { } - this(SomeOtherClassThen someOtherClassThen) - { + this(SomeOtherClassThen someOtherClassThen) { this.someOtherClassThen = someOtherClassThen; } } - class ClassWithEmptyConstructor - { + class ClassWithEmptyConstructor { public SomeOtherClassThen someOtherClassThen; - this() - { + this() { } - this(SomeOtherClassThen someOtherClassThen) - { + this(SomeOtherClassThen someOtherClassThen) { this.someOtherClassThen = someOtherClassThen; } } - class ClassWithNonInjectableConstructor - { - this(string myName) - { + class ClassWithNonInjectableConstructor { + this(string myName) { } } - class ClassWithStructConstructor - { + class ClassWithStructConstructor { public SomeOtherClassThen someOtherClassThen; - this(Thing willNotBePicked) - { + this(Thing willNotBePicked) { } - this(SomeOtherClassThen someOtherClassThen) - { + this(SomeOtherClassThen someOtherClassThen) { this.someOtherClassThen = someOtherClassThen; } } - class TestType - { + class TestType { } - class Dependency - { + class Dependency { } - struct Thing - { + struct Thing { int x; } - class MyConfig - { + class MyConfig { @Value("conf.stuffs") int stuffs; @@ -644,105 +511,83 @@ version (unittest) Thing thing; } - class ConfigWithDefaults - { + class ConfigWithDefaults { @Value("conf.missing") int noms = 9; } - class ConfigWithMandatory - { + class ConfigWithMandatory { @MandatoryValue("conf.mustbethere") int nums; } - class IntInjector : ValueInjector!int - { - public override int get(string key) - { + class IntInjector : ValueInjector!int { + public override int get(string key) { assert(key == "conf.stuffs"); return 364; } } - class StringInjector : ValueInjector!string - { - public override string get(string key) - { + class StringInjector : ValueInjector!string { + public override string get(string key) { assert(key == "conf.name"); return "Le Chef"; } } - class ThingInjector : ValueInjector!Thing - { - public override Thing get(string key) - { + class ThingInjector : ValueInjector!Thing { + public override Thing get(string key) { assert(key == "conf.thing"); return Thing(8899); } } - class DefaultIntInjector : ValueInjector!int - { - public override int get(string key) - { + class DefaultIntInjector : ValueInjector!int { + public override int get(string key) { throw new ValueNotAvailableException(key); } } - class MandatoryAvailableIntInjector : ValueInjector!int - { - public override int get(string key) - { + class MandatoryAvailableIntInjector : ValueInjector!int { + public override int get(string key) { return 7466; } } - class MandatoryUnavailableIntInjector : ValueInjector!int - { - public override int get(string key) - { + class MandatoryUnavailableIntInjector : ValueInjector!int { + public override int get(string key) { throw new ValueNotAvailableException(key); } } - class DependencyInjectedIntInjector : ValueInjector!int - { + class DependencyInjectedIntInjector : ValueInjector!int { @Autowire public Dependency dependency; - public override int get(string key) - { + public override int get(string key) { return 2345; } } - class CircularIntInjector : ValueInjector!int - { + class CircularIntInjector : ValueInjector!int { @Autowire public ValueInjector!int dependency; private int count = 0; - public override int get(string key) - { + public override int get(string key) { count += 1; - if (count >= 3) - { + if (count >= 3) { return count; } return dependency.get(key); } } - class ValueInjectedIntInjector : ValueInjector!int - { + class ValueInjectedIntInjector : ValueInjector!int { @Value("five") public int count = 0; - public override int get(string key) - { - if (key == "five") - { + public override int get(string key) { + if (key == "five") { return 5; } @@ -750,14 +595,11 @@ version (unittest) } } - class DependencyValueInjectedIntInjector : ValueInjector!int - { + class DependencyValueInjectedIntInjector : ValueInjector!int { @Autowire public ConfigWithDefaults config; - public override int get(string key) - { - if (key == "conf.missing") - { + public override int get(string key) { + if (key == "conf.missing") { return 8899; } @@ -765,57 +607,46 @@ version (unittest) } } - class TemplatedComponent(T) - { + class TemplatedComponent(T) { @Autowire T instance; } - class CircularTemplateComponentA : TemplatedComponent!CircularTemplateComponentB - { + class CircularTemplateComponentA : TemplatedComponent!CircularTemplateComponentB { } - class CircularTemplateComponentB : TemplatedComponent!CircularTemplateComponentA - { + class CircularTemplateComponentB : TemplatedComponent!CircularTemplateComponentA { } - class ClassWithTemplatedConstructorArg(T) - { + class ClassWithTemplatedConstructorArg(T) { public TemplatedComponent!T dependency; - this(TemplatedComponent!T assignedDependency) - { + this(TemplatedComponent!T assignedDependency) { this.dependency = assignedDependency; } } - class Grandma - { + class Grandma { } - class Mommy : Grandma - { + class Mommy : Grandma { } - class Kid : Mommy - { + class Kid : Mommy { } - class AutowiredMethod - { + class AutowiredMethod { @Autowire - public int lala() - { + public int lala() { return 42; } @Autowire - public int lala(int valla) - { + public int lala(int valla) { return valla; } } diff --git a/test/poodinis/testmain.d b/test/poodinis/testmain.d index f2e6fb2..bb4380a 100644 --- a/test/poodinis/testmain.d +++ b/test/poodinis/testmain.d @@ -5,6 +5,5 @@ * The full terms of the license can be found in the LICENSE file. */ -void main() -{ +void main() { } diff --git a/test/poodinis/valueinjectiontest.d b/test/poodinis/valueinjectiontest.d index bf070c7..b74d01e 100644 --- a/test/poodinis/valueinjectiontest.d +++ b/test/poodinis/valueinjectiontest.d @@ -10,32 +10,26 @@ import poodinis.test.testclasses; import std.exception; -version (unittest) -{ +version (unittest) { - struct LocalStruct - { + struct LocalStruct { bool wasInjected = false; } - class LocalStructInjector : ValueInjector!LocalStruct - { - public override LocalStruct get(string key) - { + class LocalStructInjector : ValueInjector!LocalStruct { + public override LocalStruct get(string key) { auto data = LocalStruct(true); return data; } } - class LocalClassWithStruct - { + class LocalClassWithStruct { @Value("") public LocalStruct localStruct; } // Test injection of values - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!MyConfig; container.register!(ValueInjector!int, IntInjector); @@ -49,8 +43,7 @@ version (unittest) } // Test injection of values throws exception when injector is not there - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!MyConfig; assertThrown!ResolveException(container.resolve!MyConfig); @@ -59,8 +52,7 @@ version (unittest) } // Test injection of values with defaults - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ConfigWithDefaults; container.register!(ValueInjector!int, DefaultIntInjector); @@ -70,8 +62,7 @@ version (unittest) } // Test mandatory injection of values which are available - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ConfigWithMandatory; container.register!(ValueInjector!int, MandatoryAvailableIntInjector); @@ -81,8 +72,7 @@ version (unittest) } // Test mandatory injection of values which are not available - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ConfigWithMandatory; container.register!(ValueInjector!int, MandatoryUnavailableIntInjector); @@ -92,8 +82,7 @@ version (unittest) } // Test injecting dependencies within value injectors - unittest - { + unittest { auto container = new shared DependencyContainer(); auto dependency = new Dependency(); container.register!Dependency.existingInstance(dependency); @@ -104,8 +93,7 @@ version (unittest) } // Test injecting circular dependencies within value injectors - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(ValueInjector!int, CircularIntInjector); auto injector = cast(CircularIntInjector) container.resolve!(ValueInjector!int); @@ -115,8 +103,7 @@ version (unittest) } // Test value injection within value injectors - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(ValueInjector!int, ValueInjectedIntInjector); auto injector = cast(ValueInjectedIntInjector) container.resolve!(ValueInjector!int); @@ -125,21 +112,19 @@ version (unittest) } // Test value injection within dependencies of value injectors - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!ConfigWithDefaults; container.register!(ValueInjector!int, DependencyValueInjectedIntInjector); auto injector = cast(DependencyValueInjectedIntInjector) container.resolve!( - ValueInjector!int); + ValueInjector!int); assert(injector.config.noms == 8899); } // Test resolving locally defined struct injector (github issue #20) - unittest - { + unittest { auto container = new shared DependencyContainer(); container.register!(ValueInjector!LocalStruct, LocalStructInjector); container.register!LocalClassWithStruct;