mirror of
https://github.com/mbierlee/poodinis.git
synced 2024-11-15 04:04:01 +01:00
Add pre-destruction
This commit is contained in:
parent
fbef764b48
commit
b6dea95c0d
|
@ -4,6 +4,8 @@ Poodinis Changelog
|
||||||
* ADD value injection. Members with UDA @Value will be attempted to be injected with a value-type. See tutorial and examples for more info.
|
* ADD value injection. Members with UDA @Value will be attempted to be injected with a value-type. See tutorial and examples for more info.
|
||||||
* ADD Phobos 2.072.1 forwards-compatibility for D/Phobos 2.066.1. This means you can use Poodinis with D/Phobos 2.066.1 compatible compilers such as GDC.
|
* ADD Phobos 2.072.1 forwards-compatibility for D/Phobos 2.066.1. This means you can use Poodinis with D/Phobos 2.066.1 compatible compilers such as GDC.
|
||||||
* ADD @PostConstruct UDA for marking methods which should be called after a dependency is resolved and autowired.
|
* ADD @PostConstruct UDA for marking methods which should be called after a dependency is resolved and autowired.
|
||||||
|
* ADD @PreDestroy UDA for marking methods which should be called when the container loses a dependency's registration. It is called when
|
||||||
|
removeRegistration or clearAllRegistrations is called. It is also called when the container is destroyed.
|
||||||
* FIX nullpointer exception in instance factory when debugging with poodinisVerbose
|
* FIX nullpointer exception in instance factory when debugging with poodinisVerbose
|
||||||
|
|
||||||
**Version 7.0.1**
|
**Version 7.0.1**
|
||||||
|
|
|
@ -257,9 +257,23 @@ class AutowiredRegistration(RegistrationType : Object) : Registration {
|
||||||
originatingContainer.autowire(instance);
|
originatingContainer.autowire(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.preDestructor = getPreDestructor(instance);
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void delegate() getPreDestructor(RegistrationType instance) {
|
||||||
|
void delegate() preDestructor = null;
|
||||||
|
foreach (memberName; __traits(allMembers, RegistrationType)) {
|
||||||
|
static if (__traits(getProtection, __traits(getMember, instance, memberName)) == "public"
|
||||||
|
&& isCallable!(__traits(getMember, instance, memberName))
|
||||||
|
&& hasUDA!(__traits(getMember, instance, memberName), PreDestroy)) {
|
||||||
|
preDestructor = &__traits(getMember, instance, memberName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return preDestructor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AutowireInstantiationContext : InstantiationContext {
|
class AutowireInstantiationContext : InstantiationContext {
|
||||||
|
|
|
@ -91,6 +91,15 @@ public enum ResolveOption {
|
||||||
*/
|
*/
|
||||||
struct PostConstruct {}
|
struct PostConstruct {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Methods marked with this UDA within dependencies are called before the container
|
||||||
|
* loses the dependency's registration.
|
||||||
|
*
|
||||||
|
* This method is called when removeRegistration or clearAllRegistrations is called.
|
||||||
|
* It will also be called when the container's destructor is called.
|
||||||
|
*/
|
||||||
|
struct PreDestroy {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The dependency container maintains all dependencies registered with it.
|
* The dependency container maintains all dependencies registered with it.
|
||||||
*
|
*
|
||||||
|
@ -109,6 +118,10 @@ synchronized class DependencyContainer {
|
||||||
private RegistrationOption persistentRegistrationOptions;
|
private RegistrationOption persistentRegistrationOptions;
|
||||||
private ResolveOption persistentResolveOptions;
|
private ResolveOption persistentResolveOptions;
|
||||||
|
|
||||||
|
~this() {
|
||||||
|
clearAllRegistrations();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a dependency by concrete class type.
|
* Register a dependency by concrete class type.
|
||||||
*
|
*
|
||||||
|
@ -390,6 +403,9 @@ synchronized class DependencyContainer {
|
||||||
* Clears all dependency registrations managed by this container.
|
* Clears all dependency registrations managed by this container.
|
||||||
*/
|
*/
|
||||||
public void clearAllRegistrations() {
|
public void clearAllRegistrations() {
|
||||||
|
foreach(registrationsOfType; registrations) {
|
||||||
|
callPreDestructorsOfRegistrations(registrationsOfType);
|
||||||
|
}
|
||||||
registrations.destroy();
|
registrations.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,9 +420,20 @@ synchronized class DependencyContainer {
|
||||||
* ---
|
* ---
|
||||||
*/
|
*/
|
||||||
public void removeRegistration(RegistrationType)() {
|
public void removeRegistration(RegistrationType)() {
|
||||||
|
auto registrationsOfType = *(typeid(RegistrationType) in registrations);
|
||||||
|
callPreDestructorsOfRegistrations(registrationsOfType);
|
||||||
registrations.remove(typeid(RegistrationType));
|
registrations.remove(typeid(RegistrationType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void callPreDestructorsOfRegistrations(shared(Registration[]) registrations) {
|
||||||
|
foreach(registration; registrations) {
|
||||||
|
Registration unsharedRegistration = cast(Registration) registration;
|
||||||
|
if (unsharedRegistration.preDestructor !is null) {
|
||||||
|
unsharedRegistration.preDestructor()();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a global singleton instance of a dependency container.
|
* Returns a global singleton instance of a dependency container.
|
||||||
* Deprecated: create new instance with new keyword or implement your own singleton factory (method)
|
* Deprecated: create new instance with new keyword or implement your own singleton factory (method)
|
||||||
|
|
|
@ -22,6 +22,7 @@ class Registration {
|
||||||
private Registration linkedRegistration;
|
private Registration linkedRegistration;
|
||||||
private shared(DependencyContainer) _originatingContainer;
|
private shared(DependencyContainer) _originatingContainer;
|
||||||
private InstanceFactory _instanceFactory;
|
private InstanceFactory _instanceFactory;
|
||||||
|
private void delegate() _preDestructor;
|
||||||
|
|
||||||
public @property registeredType() {
|
public @property registeredType() {
|
||||||
return _registeredType;
|
return _registeredType;
|
||||||
|
@ -39,6 +40,14 @@ class Registration {
|
||||||
return _instanceFactory;
|
return _instanceFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @property preDestructor() {
|
||||||
|
return _preDestructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected @property preDestructor(void delegate() preDestructor) {
|
||||||
|
_preDestructor = preDestructor;
|
||||||
|
}
|
||||||
|
|
||||||
this(TypeInfo registeredType, TypeInfo_Class instanceType, InstanceFactory instanceFactory, shared(DependencyContainer) originatingContainer) {
|
this(TypeInfo registeredType, TypeInfo_Class instanceType, InstanceFactory instanceFactory, shared(DependencyContainer) originatingContainer) {
|
||||||
this._registeredType = registeredType;
|
this._registeredType = registeredType;
|
||||||
this._instanceType = instanceType;
|
this._instanceType = instanceType;
|
||||||
|
|
|
@ -95,6 +95,13 @@ version(unittest) {
|
||||||
public ComponentA unrelated;
|
public ComponentA unrelated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestInjector : ValueInjector!int {
|
||||||
|
public override int get(string key) {
|
||||||
|
assert(key == "values.int");
|
||||||
|
return 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Test autowiring concrete type to existing instance
|
// Test autowiring concrete type to existing instance
|
||||||
unittest {
|
unittest {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
|
@ -252,12 +259,6 @@ version(unittest) {
|
||||||
// Test autowiring class using value injection
|
// Test autowiring class using value injection
|
||||||
unittest {
|
unittest {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
class TestInjector : ValueInjector!int {
|
|
||||||
public override int get(string key) {
|
|
||||||
assert(key == "values.int");
|
|
||||||
return 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register!(ValueInjector!int, TestInjector);
|
container.register!(ValueInjector!int, TestInjector);
|
||||||
container.register!ComponentA;
|
container.register!ComponentA;
|
||||||
|
|
|
@ -200,6 +200,21 @@ version(unittest) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PreDestroyerOfFates {
|
||||||
|
public bool preDestroyWasCalled = false;
|
||||||
|
|
||||||
|
@PreDestroy
|
||||||
|
public void callMeMaybe() {
|
||||||
|
preDestroyWasCalled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class IntInjector : ValueInjector!int {
|
||||||
|
int get(string key) {
|
||||||
|
return 8783;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Test register concrete type
|
// Test register concrete type
|
||||||
unittest {
|
unittest {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
|
@ -704,16 +719,28 @@ version(unittest) {
|
||||||
|
|
||||||
// Test postconstruction happens after autowiring and value injection
|
// Test postconstruction happens after autowiring and value injection
|
||||||
unittest {
|
unittest {
|
||||||
class IntInjector : ValueInjector!int {
|
|
||||||
int get(string key) {
|
|
||||||
return 8783;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
container.register!(ValueInjector!int, IntInjector);
|
container.register!(ValueInjector!int, IntInjector);
|
||||||
container.register!PostConstructionDependency;
|
container.register!PostConstructionDependency;
|
||||||
container.register!PostConstructWithAutowiring;
|
container.register!PostConstructWithAutowiring;
|
||||||
auto instance = container.resolve!PostConstructWithAutowiring;
|
auto instance = container.resolve!PostConstructWithAutowiring;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test PreDestroy is called when removing a registration
|
||||||
|
unittest {
|
||||||
|
auto container = new shared DependencyContainer();
|
||||||
|
container.register!PreDestroyerOfFates;
|
||||||
|
auto instance = container.resolve!PreDestroyerOfFates;
|
||||||
|
container.removeRegistration!PreDestroyerOfFates;
|
||||||
|
assert(instance.preDestroyWasCalled == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test PreDestroy is called when removing all registrations
|
||||||
|
unittest {
|
||||||
|
auto container = new shared DependencyContainer();
|
||||||
|
container.register!PreDestroyerOfFates;
|
||||||
|
auto instance = container.resolve!PreDestroyerOfFates;
|
||||||
|
container.clearAllRegistrations();
|
||||||
|
assert(instance.preDestroyWasCalled == true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,32 +37,99 @@ version(unittest) {
|
||||||
int nums;
|
int nums;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
assert(key == "conf.name");
|
||||||
|
return "Le Chef";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
throw new ValueNotAvailableException(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MandatoryAvailableIntInjector : ValueInjector!int {
|
||||||
|
public override int get(string key) {
|
||||||
|
return 7466;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MandatoryUnavailableIntInjector : ValueInjector!int {
|
||||||
|
public override int get(string key) {
|
||||||
|
throw new ValueNotAvailableException(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DependencyInjectedIntInjector : ValueInjector!int {
|
||||||
|
@Autowire
|
||||||
|
public Dependency dependency;
|
||||||
|
|
||||||
|
public override int get(string key) {
|
||||||
|
return 2345;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CircularIntInjector : ValueInjector!int {
|
||||||
|
@Autowire
|
||||||
|
public ValueInjector!int dependency;
|
||||||
|
|
||||||
|
private int count = 0;
|
||||||
|
|
||||||
|
public override int get(string key) {
|
||||||
|
count += 1;
|
||||||
|
if (count >= 3) {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
return dependency.get(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ValueInjectedIntInjector : ValueInjector!int {
|
||||||
|
@Value("five")
|
||||||
|
public int count = 0;
|
||||||
|
|
||||||
|
public override int get(string key) {
|
||||||
|
if (key == "five") {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DependencyValueInjectedIntInjector : ValueInjector!int {
|
||||||
|
@Autowire
|
||||||
|
public ConfigWithDefaults config;
|
||||||
|
|
||||||
|
public override int get(string key) {
|
||||||
|
if (key == "conf.missing") {
|
||||||
|
return 8899;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Test injection of values
|
// Test injection of values
|
||||||
unittest {
|
unittest {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
container.register!MyConfig;
|
container.register!MyConfig;
|
||||||
|
|
||||||
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) {
|
|
||||||
assert(key == "conf.name");
|
|
||||||
return "Le Chef";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ThingInjector : ValueInjector!Thing {
|
|
||||||
public override Thing get(string key) {
|
|
||||||
assert(key == "conf.thing");
|
|
||||||
return Thing(8899);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register!(ValueInjector!int, IntInjector);
|
container.register!(ValueInjector!int, IntInjector);
|
||||||
container.register!(ValueInjector!string, StringInjector);
|
container.register!(ValueInjector!string, StringInjector);
|
||||||
container.register!(ValueInjector!Thing, ThingInjector);
|
container.register!(ValueInjector!Thing, ThingInjector);
|
||||||
|
@ -86,14 +153,7 @@ version(unittest) {
|
||||||
unittest {
|
unittest {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
container.register!ConfigWithDefaults;
|
container.register!ConfigWithDefaults;
|
||||||
|
container.register!(ValueInjector!int, DefaultIntInjector);
|
||||||
class IntInjector : ValueInjector!int {
|
|
||||||
public override int get(string key) {
|
|
||||||
throw new ValueNotAvailableException(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register!(ValueInjector!int, IntInjector);
|
|
||||||
|
|
||||||
auto instance = container.resolve!ConfigWithDefaults;
|
auto instance = container.resolve!ConfigWithDefaults;
|
||||||
assert(instance.noms == 9);
|
assert(instance.noms == 9);
|
||||||
|
@ -103,14 +163,7 @@ version(unittest) {
|
||||||
unittest {
|
unittest {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
container.register!ConfigWithMandatory;
|
container.register!ConfigWithMandatory;
|
||||||
|
container.register!(ValueInjector!int, MandatoryAvailableIntInjector);
|
||||||
class IntInjector : ValueInjector!int {
|
|
||||||
public override int get(string key) {
|
|
||||||
return 7466;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register!(ValueInjector!int, IntInjector);
|
|
||||||
|
|
||||||
auto instance = container.resolve!ConfigWithMandatory;
|
auto instance = container.resolve!ConfigWithMandatory;
|
||||||
assert(instance.nums == 7466);
|
assert(instance.nums == 7466);
|
||||||
|
@ -120,14 +173,7 @@ version(unittest) {
|
||||||
unittest {
|
unittest {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
container.register!ConfigWithMandatory;
|
container.register!ConfigWithMandatory;
|
||||||
|
container.register!(ValueInjector!int, MandatoryUnavailableIntInjector);
|
||||||
class IntInjector : ValueInjector!int {
|
|
||||||
public override int get(string key) {
|
|
||||||
throw new ValueNotAvailableException(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register!(ValueInjector!int, IntInjector);
|
|
||||||
|
|
||||||
assertThrown!ResolveException(container.resolve!ConfigWithMandatory);
|
assertThrown!ResolveException(container.resolve!ConfigWithMandatory);
|
||||||
assertThrown!ValueInjectionException(autowire(container, new ConfigWithMandatory()));
|
assertThrown!ValueInjectionException(autowire(container, new ConfigWithMandatory()));
|
||||||
|
@ -138,19 +184,8 @@ version(unittest) {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
auto dependency = new Dependency();
|
auto dependency = new Dependency();
|
||||||
container.register!Dependency.existingInstance(dependency);
|
container.register!Dependency.existingInstance(dependency);
|
||||||
|
container.register!(ValueInjector!int, DependencyInjectedIntInjector);
|
||||||
class IntInjector : ValueInjector!int {
|
auto injector = cast(DependencyInjectedIntInjector) container.resolve!(ValueInjector!int);
|
||||||
|
|
||||||
@Autowire
|
|
||||||
public Dependency dependency;
|
|
||||||
|
|
||||||
public override int get(string key) {
|
|
||||||
return 2345;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register!(ValueInjector!int, IntInjector);
|
|
||||||
auto injector = cast(IntInjector) container.resolve!(ValueInjector!int);
|
|
||||||
|
|
||||||
assert(injector.dependency is dependency);
|
assert(injector.dependency is dependency);
|
||||||
}
|
}
|
||||||
|
@ -158,25 +193,8 @@ version(unittest) {
|
||||||
// Test injecting circular dependencies within value injectors
|
// Test injecting circular dependencies within value injectors
|
||||||
unittest {
|
unittest {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
|
container.register!(ValueInjector!int, CircularIntInjector);
|
||||||
class IntInjector : ValueInjector!int {
|
auto injector = cast(CircularIntInjector) container.resolve!(ValueInjector!int);
|
||||||
|
|
||||||
@Autowire
|
|
||||||
public ValueInjector!int dependency;
|
|
||||||
|
|
||||||
private int count = 0;
|
|
||||||
|
|
||||||
public override int get(string key) {
|
|
||||||
count += 1;
|
|
||||||
if (count >= 3) {
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
return dependency.get(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register!(ValueInjector!int, IntInjector);
|
|
||||||
auto injector = cast(IntInjector) container.resolve!(ValueInjector!int);
|
|
||||||
|
|
||||||
assert(injector.dependency is injector);
|
assert(injector.dependency is injector);
|
||||||
assert(injector.get("whatever") == 3);
|
assert(injector.get("whatever") == 3);
|
||||||
|
@ -185,23 +203,8 @@ version(unittest) {
|
||||||
// Test value injection within value injectors
|
// Test value injection within value injectors
|
||||||
unittest {
|
unittest {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
|
container.register!(ValueInjector!int, ValueInjectedIntInjector);
|
||||||
class IntInjector : ValueInjector!int {
|
auto injector = cast(ValueInjectedIntInjector) container.resolve!(ValueInjector!int);
|
||||||
|
|
||||||
@Value("five")
|
|
||||||
public int count = 0;
|
|
||||||
|
|
||||||
public override int get(string key) {
|
|
||||||
if (key == "five") {
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register!(ValueInjector!int, IntInjector);
|
|
||||||
auto injector = cast(IntInjector) container.resolve!(ValueInjector!int);
|
|
||||||
|
|
||||||
assert(injector.count == 5);
|
assert(injector.count == 5);
|
||||||
}
|
}
|
||||||
|
@ -211,22 +214,8 @@ version(unittest) {
|
||||||
auto container = new shared DependencyContainer();
|
auto container = new shared DependencyContainer();
|
||||||
container.register!ConfigWithDefaults;
|
container.register!ConfigWithDefaults;
|
||||||
|
|
||||||
class IntInjector : ValueInjector!int {
|
container.register!(ValueInjector!int, DependencyValueInjectedIntInjector);
|
||||||
|
auto injector = cast(DependencyValueInjectedIntInjector) container.resolve!(ValueInjector!int);
|
||||||
@Autowire
|
|
||||||
public ConfigWithDefaults config;
|
|
||||||
|
|
||||||
public override int get(string key) {
|
|
||||||
if (key == "conf.missing") {
|
|
||||||
return 8899;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container.register!(ValueInjector!int, IntInjector);
|
|
||||||
auto injector = cast(IntInjector) container.resolve!(ValueInjector!int);
|
|
||||||
|
|
||||||
assert(injector.config.noms == 8899);
|
assert(injector.config.noms == 8899);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue