Skip to content

Commit

Permalink
New builder functions with resolver parameter
Browse files Browse the repository at this point in the history
  • Loading branch information
ref-humbold committed Jul 28, 2024
1 parent 91d737a commit 9b700b0
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 66 deletions.
61 changes: 19 additions & 42 deletions src/main/java/newdicontainer/DiContainer.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package newdicontainer;

import java.util.function.Supplier;
import java.util.function.Function;

import dicontainer.DiException;
import newdicontainer.annotation.Dependency;
import newdicontainer.dictionary.ConstructionPolicy;
import newdicontainer.dictionary.DiDictionary;
import newdicontainer.resolver.DiResolver;
import newdicontainer.dictionary.DependencyRegistry;
import newdicontainer.resolver.TypeResolver;

public final class DiContainer
implements DiResolver
{
private final DiDictionary diDictionary;
private final DiResolver diResolver;
private final DependencyRegistry registry;
private final TypeResolver resolver;

public DiContainer()
{
diDictionary = new DiDictionary();
diResolver = new DiResolver(diDictionary);
registry = new DependencyRegistry();
resolver = new TypeResolver(registry);
}

/**
Expand All @@ -26,7 +25,7 @@ public DiContainer()
*/
public <T> DiContainer registerConstruction(Class<T> type)
{
diDictionary.addType(type, ConstructionPolicy.CONSTRUCT, null);
registry.addType(type, ConstructionPolicy.CONSTRUCT, null);
return this;
}

Expand All @@ -36,9 +35,9 @@ public <T> DiContainer registerConstruction(Class<T> type)
* @param builder builder function of instance
* @return {@code this} for method chaining
*/
public <T> DiContainer registerConstruction(Class<T> type, Supplier<T> builder)
public <T> DiContainer registerConstruction(Class<T> type, Function<DiResolver, T> builder)
{
diDictionary.addType(type, ConstructionPolicy.CONSTRUCT, builder);
registry.addType(type, ConstructionPolicy.CONSTRUCT, builder);
return this;
}

Expand All @@ -50,7 +49,7 @@ public <T> DiContainer registerConstruction(Class<T> type, Supplier<T> builder)
*/
public <T> DiContainer registerConstruction(Class<T> supertype, Class<? extends T> subtype)
{
diDictionary.addType(supertype, subtype, ConstructionPolicy.CONSTRUCT);
registry.addType(supertype, subtype, ConstructionPolicy.CONSTRUCT);
return this;
}

Expand All @@ -61,7 +60,7 @@ public <T> DiContainer registerConstruction(Class<T> supertype, Class<? extends
*/
public <T> DiContainer registerSingleton(Class<T> type)
{
diDictionary.addType(type, ConstructionPolicy.SINGLETON, null);
registry.addType(type, ConstructionPolicy.SINGLETON, null);
return this;
}

Expand All @@ -70,9 +69,9 @@ public <T> DiContainer registerSingleton(Class<T> type)
* @param type type class
* @return {@code this} for method chaining
*/
public <T> DiContainer registerSingleton(Class<T> type, Supplier<T> builder)
public <T> DiContainer registerSingleton(Class<T> type, Function<DiResolver, T> builder)
{
diDictionary.addType(type, ConstructionPolicy.SINGLETON, builder);
registry.addType(type, ConstructionPolicy.SINGLETON, builder);
return this;
}

Expand All @@ -85,7 +84,7 @@ public <T> DiContainer registerSingleton(Class<T> type, Supplier<T> builder)
public <T> DiContainer registerSingleton(
Class<T> supertype, Class<? extends T> subtype)
{
diDictionary.addType(supertype, subtype, ConstructionPolicy.SINGLETON);
registry.addType(supertype, subtype, ConstructionPolicy.SINGLETON);
return this;
}

Expand All @@ -97,35 +96,13 @@ public <T> DiContainer registerSingleton(
*/
public <T> DiContainer registerInstance(Class<T> type, T instance)
{
diDictionary.addInstance(type, instance);
registry.addInstance(type, instance);
return this;
}

/**
* Resolve all dependencies and construct a new instance of given type using {@link Dependency}.
* @param type type class
* @return new instance
* @throws DiException if type cannot be resolved
*/
@Override
public <T> T resolve(Class<T> type)
{
return diResolver.construct(type);
}

/**
* Resolve all dependencies and construct a new instance of given type using {@link Dependency}.
* @param type type class
* @return new instance, or {@code null} if type cannot be resolved.
*/
public <T> T resolveOrNull(Class<T> type)
{
try
{
return resolve(type);
}
catch(DiException ex)
{
return null;
}
return resolver.resolve(type);
}
}
32 changes: 32 additions & 0 deletions src/main/java/newdicontainer/DiResolver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package newdicontainer;

import dicontainer.DiException;
import newdicontainer.annotation.Dependency;

public interface DiResolver
{
/**
* Resolve all dependencies and construct a new instance of given type using {@link Dependency}.
* @param type type class
* @return new instance
* @throws DiException if type cannot be resolved
*/
<T> T resolve(Class<T> type);

/**
* Resolve all dependencies and construct a new instance of given type using {@link Dependency}.
* @param type type class
* @return new instance, or {@code null} if type cannot be resolved.
*/
default <T> T resolveOrNull(Class<T> type)
{
try
{
return resolve(type);
}
catch(DiException ex)
{
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package newdicontainer.dictionary;

import java.util.function.Supplier;
import java.util.function.Function;

import dicontainer.dictionary.exception.RegistrationException;
import dicontainer.dictionary.valuetypes.Instance;
import newdicontainer.DiResolver;
import newdicontainer.dictionary.valuetypes.Subtype;

public class DiDictionary
public class DependencyRegistry
{
private final TypesDictionary typesDictionary = new TypesDictionary();
private final InstancesDictionary instancesDictionary = new InstancesDictionary();

public <T> void addType(Class<T> type, ConstructionPolicy policy, Supplier<T> builder)
public <T> void addType(
Class<T> type,
ConstructionPolicy policy,
Function<DiResolver, T> builder)
{
validateRegisteredType(type);
typesDictionary.insert(type, policy, builder);
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/newdicontainer/dictionary/TypesDictionary.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;
import java.util.function.Function;

import dicontainer.dictionary.exception.AbstractTypeException;
import dicontainer.dictionary.exception.AnnotatedTypeRegistrationException;
import dicontainer.dictionary.exception.MixingPoliciesException;
import dicontainer.dictionary.exception.NotDerivedTypeException;
import dicontainer.resolver.exception.MissingDependenciesException;
import newdicontainer.DiResolver;
import newdicontainer.annotation.Register;
import newdicontainer.annotation.SelfRegister;
import newdicontainer.dictionary.valuetypes.Subtype;
Expand All @@ -18,8 +19,7 @@ class TypesDictionary
private final Map<Class<?>, Subtype<?>> typesMap = new HashMap<>();

@SuppressWarnings("unchecked")
<T> void insert(
Class<T> type, ConstructionPolicy policy, Supplier<T> builder)
<T> void insert(Class<T> type, ConstructionPolicy policy, Function<DiResolver, T> builder)
{
validateAnnotation(type);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package newdicontainer.dictionary.valuetypes;

import java.util.Optional;
import java.util.function.Supplier;
import java.util.function.Function;

import newdicontainer.DiResolver;
import newdicontainer.dictionary.ConstructionPolicy;

public record Subtype<T>(
Class<T> subtype, ConstructionPolicy policy, Optional<Supplier<T>> builder)
Class<T> subtype, ConstructionPolicy policy, Optional<Function<DiResolver, T>> builder)
{
public Subtype(Class<T> subtype, ConstructionPolicy policy)
{
this(subtype, policy, Optional.empty());
}

public Subtype(Class<T> subtype, ConstructionPolicy policy, Supplier<T> builder)
public Subtype(Class<T> subtype, ConstructionPolicy policy, Function<DiResolver, T> builder)
{
this(subtype, policy, Optional.ofNullable(builder));
}
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/newdicontainer/resolver/ConstructorResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

class ConstructorResolver
{
private final DiResolver resolver;
private final TypeResolver resolver;

ConstructorResolver(DiResolver resolver)
ConstructorResolver(TypeResolver resolver)
{
this.resolver = resolver;
}
Expand All @@ -32,10 +32,10 @@ <T> T resolve(Class<T> type, Stack<Class<?>> path)

private <T> T resolveType(Class<T> type, Stack<Class<?>> path)
{
return resolver.dictionary.findInstance(type).extract(() -> {
Class<? extends T> subtype = resolver.dictionary.findType(type).subtype();
return resolver.registry.findInstance(type).extract(() -> {
Class<? extends T> subtype = resolver.registry.findType(type).subtype();
T object = construct(new TypeConstructors<>(subtype), path);
resolver.dictionary.addSingletonInstance(type, object);
resolver.registry.addSingletonInstance(type, object);
return object;
});
}
Expand Down Expand Up @@ -85,7 +85,7 @@ private <T> Instance<T> invoke(Constructor<T> constructor, Stack<Class<?>> path)
"Dependencies resolving detected a cycle detected between %s and %s",
parameter.getName(), typename)));

if(!resolver.dictionary.contains(parameter))
if(!resolver.registry.contains(parameter))
return Instance.none(new MissingDependenciesException(
String.format("No dependency for type %s found when resolving type %s",
parameter.getName(), typename)));
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/newdicontainer/resolver/SetterResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
class SetterResolver
{
private static final String SETTER_NAME_REGEX = "^set[a-z]?[A-Z](\\w|\\d)*";
private final DiResolver resolver;
private final TypeResolver resolver;

SetterResolver(DiResolver resolver)
SetterResolver(TypeResolver resolver)
{
this.resolver = resolver;
}
Expand All @@ -41,7 +41,7 @@ private <T> void invoke(T object, Method setter, Stack<Class<?>> path)

for(Class<?> parameter : setter.getParameterTypes())
{
if(!resolver.dictionary.contains(parameter))
if(!resolver.registry.contains(parameter))
throw new MissingDependenciesException(
String.format("No dependency for type %s found when resolving type %s",
parameter.getName(), typename));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,23 @@

import java.util.Stack;

import newdicontainer.dictionary.DiDictionary;
import newdicontainer.DiResolver;
import newdicontainer.dictionary.DependencyRegistry;

public class DiResolver
public class TypeResolver
implements DiResolver
{
final DiDictionary dictionary;
final DependencyRegistry registry;
private final ConstructorResolver constructorResolver = new ConstructorResolver(this);
private final SetterResolver setterResolver = new SetterResolver(this);

public DiResolver(DiDictionary dictionary)
public TypeResolver(DependencyRegistry registry)
{
this.dictionary = dictionary;
this.registry = registry;
}

public <T> T construct(Class<T> type)
@Override
public <T> T resolve(Class<T> type)
{
return resolve(type, new Stack<>());
}
Expand Down

0 comments on commit 9b700b0

Please sign in to comment.