From 0a0ac1bba210d45d73c8bc40e3bbd927e873bce2 Mon Sep 17 00:00:00 2001 From: Mike Bierlee Date: Sun, 8 Jun 2014 17:40:21 +0200 Subject: [PATCH] Add more future work --- README.md | 269 +++++++++++++++++++++++++++--------------------------- 1 file changed, 135 insertions(+), 134 deletions(-) diff --git a/README.md b/README.md index 08ed660..85a35c8 100644 --- a/README.md +++ b/README.md @@ -1,134 +1,135 @@ -Poodinis Dependency Injection Framework -======================================= -Version 0.1 -Copyright 2014 Mike bierlee -Licensed under the terms of the MIT license - See [LICENSE.txt](LICENSE.txt) - -Poodinis is a dependency injection framework for the D programming language. It is inspired by the [Spring Framework] and [Hypodermic] IoC container for C++. Poodinis supports registering and resolving classes either by concrete type or interface. Automatic injection of dependencies is supported through the use of UDAs (Referred to as autowiring). - -Uses D 2.065.0 and Phobos. - -History -------- -For a full overview of changes, see [CHANGES.md](CHANGES.md) - -Getting started ---------------- -###DUB Dependency -See the Poodinis [DUB project page] for instructions on how to include Poodinis into your project. - -###Quickstart -The following example shows the typical usage of Poodinis: -```d -import poodinis.container; // The only import needed for now - -interface Database{}; -class RelationalDatabase : Database {} - -class DataWriter { - @Autowire - public Database database; // Automatically injected when class is resolved -} - -void main() { - auto container = Container.getInstance(); - container.register!DataWriter; - container.register!(Database, RelationalDatabase); - - auto writer = container.resolve!DataWriter; -} -``` - -### The container -To register a class, a new dependency container must be instantiated: -```d -// Register a private container -auto container = new Container(); -// Or use the singleton container -container = Container.getInstance(); -``` -###Registering dependencies -They make dependencies available, they have to be registered: -```d -// Register concrete class -container.register!ExampleClass; -// Register by interface -container.register!(ExampleInterface, ExampleClass); -``` -In the above example, dependencies on the concrete class and interface will resolve an instance of class ExampleClass. Registering a class by interface does not automatically register by concrete type. - -###Resolving dependencies -To manually resolve a dependency, all you have to do is resolve the dependency's type using the container in which it is registered: -```d -auto exampleClassInstance = container.resolve!ExampleClass; -``` -If the class is registered by interface and not by concrete type, you cannot resolve the class by concrete type. Registration of both a concrete type and interface type will resolve different registrations, returning different instances: - -```d -auto exampleClassInstance = container.resolve!ExampleClass; -auto exampleClassInstance2 = container.resolve!ExampleInterface; -assert(exampleClassInstance !is exampleClassInstance2); -``` - -###Dependency scopes -With dependency scopes, you can control how a dependency is resolved. The scope determines which instance is returned, be it the same each time or a new one. The following scopes are available: - -* Resolve a dependency using a single instance (default): - -```d -container.register!(ExampleClass).singleInstance(); -``` -* Resolve a dependency with a new instance each time it is resolved: - -```d -container.register!(ExampleClass).newInstance(); -``` -* Resolve a dependency using a pre-existing instance - -```d -auto preExistingInstance = new ExampleClass(); -container.register!(ExampleClass).existingInstance(preExistingInstance); -``` - -###Autowiring -The real value of any dependency injection framework comes from its ability to autowire dependencies. Poodinis supports autowiring by simply applying the **@Autowire** UDA to a member of a class: -```d -class ExampleClassA {} - -class ExampleClassB { - @Autowire - public ExampleClassA dependency; -} - -container.register!ExampleClassA; -auto exampleInstance = new ExampleClassB(); -container.autowire!ExampleClassB(exampleInstance); -assert(exampleInstance.dependency !is null); -``` -At the moment, it is only possible to autowire public members or properties. - -Dependencies are automatically autowired when a class is resolved. So when you register ExampleClassB, its member, *dependency*, is automatically injected: -```d -container.register!ExampleClassA; -container.register!ExampleClassB; -auto instance = container.resolve!ExampleClassB; -assert(instance.dependency !is null); -``` -If an interface is to be autowired, you must register a concrete class by interface. Any class registered by concrete type can only be injected when a dependency on a concrete type is autowired. - -###Circular dependencies -Poodinis can autowire circular dependencies when they are registered with singleInstance or existingInstance registration scopes. See Known issues for the limitations on newInstance scopes. - -Known issues ------------- -* Due to preventive measures of recursion issues in circular dependencies, registrations which are supposed to yield new instances will not autowire classes for which a circular dependency is detected. A new instance will be resolved but the instance's members will not be autowired. - -Future Work ------------ -* Thread safety -* Component scan (auto-registration) - -[Spring Framework]: http://projects.spring.io/spring-framework/ -[Hypodermic]: https://code.google.com/p/hypodermic/ -[DUB]: http://code.dlang.org/ -[DUB project page]: http://code.dlang.org/packages/poodinis +Poodinis Dependency Injection Framework +======================================= +Version 0.1 +Copyright 2014 Mike bierlee +Licensed under the terms of the MIT license - See [LICENSE.txt](LICENSE.txt) + +Poodinis is a dependency injection framework for the D programming language. It is inspired by the [Spring Framework] and [Hypodermic] IoC container for C++. Poodinis supports registering and resolving classes either by concrete type or interface. Automatic injection of dependencies is supported through the use of UDAs (Referred to as autowiring). + +Uses D 2.065.0 and Phobos. + +History +------- +For a full overview of changes, see [CHANGES.md](CHANGES.md) + +Getting started +--------------- +###DUB Dependency +See the Poodinis [DUB project page] for instructions on how to include Poodinis into your project. + +###Quickstart +The following example shows the typical usage of Poodinis: +```d +import poodinis.container; // The only import needed for now + +interface Database{}; +class RelationalDatabase : Database {} + +class DataWriter { + @Autowire + public Database database; // Automatically injected when class is resolved +} + +void main() { + auto container = Container.getInstance(); + container.register!DataWriter; + container.register!(Database, RelationalDatabase); + + auto writer = container.resolve!DataWriter; +} +``` + +### The container +To register a class, a new dependency container must be instantiated: +```d +// Register a private container +auto container = new Container(); +// Or use the singleton container +container = Container.getInstance(); +``` +###Registering dependencies +They make dependencies available, they have to be registered: +```d +// Register concrete class +container.register!ExampleClass; +// Register by interface +container.register!(ExampleInterface, ExampleClass); +``` +In the above example, dependencies on the concrete class and interface will resolve an instance of class ExampleClass. Registering a class by interface does not automatically register by concrete type. + +###Resolving dependencies +To manually resolve a dependency, all you have to do is resolve the dependency's type using the container in which it is registered: +```d +auto exampleClassInstance = container.resolve!ExampleClass; +``` +If the class is registered by interface and not by concrete type, you cannot resolve the class by concrete type. Registration of both a concrete type and interface type will resolve different registrations, returning different instances: + +```d +auto exampleClassInstance = container.resolve!ExampleClass; +auto exampleClassInstance2 = container.resolve!ExampleInterface; +assert(exampleClassInstance !is exampleClassInstance2); +``` + +###Dependency scopes +With dependency scopes, you can control how a dependency is resolved. The scope determines which instance is returned, be it the same each time or a new one. The following scopes are available: + +* Resolve a dependency using a single instance (default): + +```d +container.register!(ExampleClass).singleInstance(); +``` +* Resolve a dependency with a new instance each time it is resolved: + +```d +container.register!(ExampleClass).newInstance(); +``` +* Resolve a dependency using a pre-existing instance + +```d +auto preExistingInstance = new ExampleClass(); +container.register!(ExampleClass).existingInstance(preExistingInstance); +``` + +###Autowiring +The real value of any dependency injection framework comes from its ability to autowire dependencies. Poodinis supports autowiring by simply applying the **@Autowire** UDA to a member of a class: +```d +class ExampleClassA {} + +class ExampleClassB { + @Autowire + public ExampleClassA dependency; +} + +container.register!ExampleClassA; +auto exampleInstance = new ExampleClassB(); +container.autowire!ExampleClassB(exampleInstance); +assert(exampleInstance.dependency !is null); +``` +At the moment, it is only possible to autowire public members or properties. + +Dependencies are automatically autowired when a class is resolved. So when you register ExampleClassB, its member, *dependency*, is automatically injected: +```d +container.register!ExampleClassA; +container.register!ExampleClassB; +auto instance = container.resolve!ExampleClassB; +assert(instance.dependency !is null); +``` +If an interface is to be autowired, you must register a concrete class by interface. Any class registered by concrete type can only be injected when a dependency on a concrete type is autowired. + +###Circular dependencies +Poodinis can autowire circular dependencies when they are registered with singleInstance or existingInstance registration scopes. See Known issues for the limitations on newInstance scopes. + +Known issues +------------ +* Due to preventive measures of recursion issues in circular dependencies, registrations which are supposed to yield new instances will not autowire classes for which a circular dependency is detected. A new instance will be resolved but the instance's members will not be autowired. + +Future Work +----------- +* Thread safety +* Component scan (auto-registration) +* Registering multiple concrete classes to the same interface + +[Spring Framework]: http://projects.spring.io/spring-framework/ +[Hypodermic]: https://code.google.com/p/hypodermic/ +[DUB]: http://code.dlang.org/ +[DUB project page]: http://code.dlang.org/packages/poodinis