Skip to content

Repository files navigation

DepenDance

💉 Inject Simplicity, Eject Complexity 🪲

 <repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependency>
<groupid>com.github.jwdeveloper.DepenDance</groupid>
<artifactid>DepenDance-Full</artifactid>
<version>0.0.20-Release</version>
</dependency> 

Depandance is the dependency injection container library. Is is quite compacts and has a lot of features you can find in the more popular DI container libraries. ## What are the dependecies? Dependecies is the fancy word for a class consturctor parameters. So the objects certain class depends on/ ## What is the dependecy injection? Is is one of the programming design patters, watch great video about it Video ## What is the dependecy injection container? It is library that helps to create instance of object with all its dependecines. At the beggining you need to register the dependecines classess to the container, then any class that was registed, can be obtained for the container.

Features

Tutorial

01 Basic

02 Object Instances

03 Lists

04 Events

05 Generic Types

06 AutoScan

07 Overriding

08 ManyConstructors

09 Fields

10 Methods

11 ResolveParameters

01 Basic

publicclass_01_Basic {
publicstaticvoidmain(String[] args) {
/* - Singleton There will be only one instance of object created by container - Transient everytime `container.find` is used new instance of object is created */DependanceContainercontainer = Dependance.newContainer()
.registerTransient(Shop.class, LocalShop.class) //registration interface to implementation
.registerSingleton(Config.class)
.registerSingleton(ShopManager.class)
.build();
ShopManagershopManager1 = container.find(ShopManager.class);
ShopManagershopManager2 = container.find(ShopManager.class);
Shopshop1 = container.find(Shop.class);
Shopshop2 = container.find(Shop.class);
Assert.assertEquals(shopManager1, shopManager2);
System.out.println("There always same instance of shop manager");
Assert.assertEquals(shopManager1.getConfig(), shopManager2.getConfig());
System.out.println("There always same instance of config");
Assert.assertNotEquals(shop1, shop2);
System.out.println("There are different instances of shop");
}
} 

02 Object Instances

publicclass_02_Object_Instances
{
publicstaticvoidmain(String[] args)
{
ConfigmyConfigInstance = newConfig();
DependanceContainercontainer = Dependance.newContainer()
.registerSingleton(Config.class, myConfigInstance) //in case we want to make instance manually we can put object as second argument
.registerTransient(LocalShop.class,(di)->
{
//more complex case, we want to find or put manually arguments to created instance//for that we can use lamda resolver that has container as input, and object instance as outputvarconfig = (Config)di.find(Config.class);
varshop = newLocalShop(config);
System.out.println("Shop has been created: "+shop);
returnshop;
})
.build();
Configconfig = container.find(Config.class);
LocalShopshop1 = container.find(LocalShop.class);
LocalShopshop2 = container.find(LocalShop.class);
Assert.assertEquals(myConfigInstance,config);
System.out.println("Config has same instance");
Assert.assertNotEquals(shop1,shop2);
System.out.println("Shops has different instances");
}
} 

03 Lists

publicclass_03_Lists {
publicstaticvoidmain(String[] args) {
DependanceContainercontainer = Dependance.newContainer()
.registerSingleton(Config.class)
.registerTransient(Shop.class, OnlineShop.class)
.registerTransient(Shop.class, LocalShop.class)
.registerTransientList(Shop.class)
.build();
List<Shop> shops = (List<Shop>) container.find(List.class, Shop.class);
for (varshop : shops) {
System.out.println("Shops: " + shop.getClass().getSimpleName());
}
Assert.assertEquals(2, shops.size());
}
} 

04 Events

publicclass_04_Events {
publicstaticvoidmain(String[] args) {
DependanceContainercontainer = Dependance.newContainer()
.registerSingleton(Shop.class, LocalShop.class)
.registerSingleton(Shop.class, OnlineShop.class)
.configure(config ->
{
config.onInjection(_04_Events::onInjection);
config.onRegistration(_04_Events::onRegistration);
})
.build();
Objectshops = container.find(Shop.class, String.class);
}
privatestaticBooleanonRegistration(OnRegistrationEventevent) {
System.out.println("onRegistration event: " + event.registrationInfo().implementation().getSimpleName());
returntrue; //If false `container.find` injection is not registered to container
}
privatestaticObjectonInjection(OnInjectionEventevent) {
varinputType = event.input();// searched class type provided as first parametersvargenericTypes = event.inputGenericParameters(); //list of generic types provided as second parametervaroutputObject = event.output(); //Target object instance type has not been found then output value is nullvarcontainer = event.container(); //access to DI containervarinjectonMetadata = event.injectionInfo();
System.out.println("OnInjection input class: " + inputType.getSimpleName());
System.out.println("OnInjection output class: " + outputObject.getClass().getSimpleName());
System.out.println("OnInjection genericTypes: " + genericTypes.length);
System.out.println("OnInjection metadata: " + injectonMetadata.toString());
returnoutputObject;
}
} 

05 Generic Types

publicclass_05_Generic_Types {
publicstaticvoidmain(String[] args) {
varcontainer = Dependance.newContainer()
.registerTransient(ExampleGenericsTypes.class)
.configure(configuration ->
{
/* * Since java is not storing information about generic type after compilation * we can not assign class with generic type to variable, so Repository<MyGenericType>.class is not possible * Therefor all cases with generic types (besides lists) must be handled manually in onInjection event */configuration.onInjection(injection ->
{
if (!injection.input().isAssignableFrom(Repository.class)) {
returninjection.output();
}
vargenericParameter = injection.inputGenericParameters()[0];
if (genericParameter.equals(OnlineShop.class)) {
returnnewRepository<OnlineShop>();
}
if (genericParameter.equals(LocalShop.class)) {
returnnewRepository<LocalShop>();
}
returnnewRepository();
});
})
.build();
//first parameter is class, second one is its generic parametervarexampleGenericsTypes = container.find(ExampleGenericsTypes.class);
Assert.assertNotNull(exampleGenericsTypes);
Assert.assertNotNull(exampleGenericsTypes.getLocalShopRepository());
Assert.assertNotNull(exampleGenericsTypes.getOnlineShopRepository());
}
publicstaticclassExampleGenericsTypes {
@GetterprivateRepository<OnlineShop> onlineShopRepository;
@GetterprivateRepository<LocalShop> localShopRepository;
publicExampleGenericsTypes(Repository<OnlineShop> onlineShopRepository,
Repository<LocalShop> localShopRepository) {
this.onlineShopRepository = onlineShopRepository;
this.localShopRepository = localShopRepository;
}
}
} 

06 AutoScan

publicclass_06_AutoScan {
/** * To avoid boring manually registering Types to container * use `scan` method that is looking for all Classes and Methods * with annotation @Injection and register it automatically */publicstaticvoidmain(String[] args) {
/* * package under which code will be scanned should be scanned * scanner is looking for all Method and Classes that are having @Injection annotation */Class<?> rootClass = _06_AutoScan.class;
DependanceContainercontainer = Dependance.newContainer()
.scan(rootClass)
.scan(options ->
{
options.setRootPackage(rootClass);
options.excludeClass("org.example.ExampleClass");
options.excludePackage(String.class.getPackageName());
})
.scan(rootClass, (scannedClasses, containerBuilder) ->
{
System.out.println("Hello from scanner those are found classes");
for (varclazz : scannedClasses)
{
System.out.println(clazz.getSimpleName());
}
System.out.println("============================================");
})
.build();
Configconfig = container.find(Config.class);
ExampleClassexampleClass = container.find(ExampleClass.class);
OnlineShoponlineShop = container.find(OnlineShop.class);
ExampleScannClassexampleScannClass = container.find(ExampleScannClass.class);
Assert.assertNotNull(config);
Assert.assertNotNull(exampleClass);
Assert.assertNotNull(onlineShop);
Assert.assertNotNull(exampleScannClass);
}
/** * This is equivalent of * <p> * container.registerTransient(OnlineShop.class,container1 -> * { * System.out.println("Hello from the online shop factory"); * return new OnlineShop(); * }) */@Injection(lifeTime = LifeTime.TRANSIENT)
privatestaticOnlineShoponlineShopFactory() {
System.out.println("Hello from the online shop factory");
returnnewOnlineShop();
}
/** * This is equivalent of * <p> * container.registerSingleton(ExampleScannClass.class); */@Injection(lifeTime = LifeTime.SINGLETON)
publicstaticclassExampleScannClass {
publicExampleScannClass() {
System.out.println("Hello world!");
}
}
} 

07 Overriding

publicclass_07_Overriding {
publicstaticvoidmain(String[] args) {
DependanceContainercontainer = Dependance.newContainer()
.registerTransient(Shop.class, OnlineShop.class)
.registerTransient(Shop.class, OfflineShop.class)
/** * By again declaring Shop but with different implementation (OnlineShop) * We are telling container to Override (OfflineShop) and always returns (OnlineShop) */
.build();
Shopshop = container.find(Shop.class);
Assert.assertEquals(OfflineShop.class, shop.getClass());
System.out.println("shop object is instance of OfflineShop Class");
}
} 

08 ManyConstructors

publicclass_08_ManyConstructors
{
/** * By the default the first constructor is always targeted for injecting parameters * However, sometimes class can have more than one constructor, or we want to use * specific one. * * To do that use @Inject annotation over wanted constructor * */publicstaticvoidmain(String[] args) {
DependanceContainercontainer = Dependance.newContainer()
.registerTransient(ExampleClass.class)
.registerTransient(ManyConstructorsExample.class)
.build();
ManyConstructorsExampleexample = container.find(ManyConstructorsExample.class);
Assert.assertNotNull(example);
System.out.println("It works!");
}
publicstaticclassManyConstructorsExample
{
publicManyConstructorsExample(Stringa, intb, booleanc)
{
}
@InjectpublicManyConstructorsExample(ExampleClassc)
{
System.out.println("Hello from constructor with ExampleClass parameter");
}
}
publicstaticclassExampleClass
{
}
} 

09 Fields

publicclass_09_Fields {
publicstaticvoidmain(String[] args) {
DependanceContainercontainer = Dependance.newContainer()
.registerTransient(_09_Fields.ExampleSerivce.class)
.registerTransient(_09_Fields.ExampleClass.class)
.build();
_09_Fields.ExampleSerivceexample = container.find(_09_Fields.ExampleSerivce.class);
Assert.assertNotNull(example);
example.exampleClass.sayIt();
}
publicstaticclassExampleSerivce {
@InjectExampleClassexampleClass;
}
publicstaticclassExampleClass {
publicvoidsayIt() {
System.out.println("Hello world!");
}
}
} 

10 Methods

publicclass_10_Methods
{
publicstaticvoidmain(String[] args) {
DependanceContainercontainer = Dependance.newContainer()
.registerTransient(_10_Methods.ExampleSerivce.class)
.registerTransient(_10_Methods.ExampleClass.class)
.build();
_10_Methods.ExampleClassexample = container.find(_10_Methods.ExampleClass.class);
Assert.assertNotNull(example);
example.sayIt();
}
publicstaticclassExampleSerivce
{
@Injection_09_Fields.ExampleClassexampleClassProvider()
{
returnnew_09_Fields.ExampleClass();
}
}
publicstaticclassExampleClass {
publicvoidsayIt() {
System.out.println("Hello world!");
}
}
} 

11 ResolveParameters

publicclass_11_ResolveParameters {
publicstaticvoidmain(String[] args) throwsException {
DependanceContainercontainer = Dependance.newContainer()
.registerTransient(_11_ResolveParameters.ExampleWithGenerics.class)
.registerTransient(_11_ResolveParameters.ExampleClass.class)
.configure(config ->
{
config.onInjection(onInjectionEvent ->
{
if (!onInjectionEvent.input().equals(ExampleWithGenerics.class)) {
returnonInjectionEvent.output();
}
vargeneicsTyles = onInjectionEvent.inputGenericParameters()[0];
if (!String.class.equals(geneicsTyles)) {
returnonInjectionEvent.output();
}
returnnewExampleWithGenerics<String>();
});
})
.build();
varmethod = _11_ResolveParameters.class.getDeclaredMethod(
"sayHello",
_11_ResolveParameters.ExampleWithGenerics.class,
_11_ResolveParameters.ExampleClass.class);
varparameters = container.resolveParameters(method);
method.invoke(null, parameters);
}
publicstaticvoidsayHello(_11_ResolveParameters.ExampleWithGenerics<String> exampleService,
_11_ResolveParameters.ExampleClassexampleClass) {
System.out.println("Hello world");
}
publicstaticclassExampleWithGenerics<T> {
}
publicstaticclassExampleClass {
}
} 

About

Simple and easy to use dependecy injection container for Java

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages