mirror of
https://github.com/mbierlee/poodinis.git
synced 2024-11-15 04:04:01 +01:00
Merge pull request #11 from tmccombs/develop
Use bit flags instead of array for options.
This commit is contained in:
commit
5943dedc95
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -15,6 +15,7 @@
|
||||||
/arrayCompletionExample
|
/arrayCompletionExample
|
||||||
/annotationsExample
|
/annotationsExample
|
||||||
/applicationContextExample
|
/applicationContextExample
|
||||||
|
/registerOnResolveExample
|
||||||
/.project
|
/.project
|
||||||
/.idea
|
/.idea
|
||||||
/*.iml
|
/*.iml
|
||||||
|
|
|
@ -32,7 +32,7 @@ void main() {
|
||||||
* By using the resolve option "registerBeforeResolving" you can register the resolved class
|
* By using the resolve option "registerBeforeResolving" you can register the resolved class
|
||||||
* immediately. Note that any autowired member will not automatically be registered as well.
|
* immediately. Note that any autowired member will not automatically be registered as well.
|
||||||
*/
|
*/
|
||||||
auto violinPlayer = dependencies.resolve!Violin([ResolveOption.registerBeforeResolving]);
|
auto violinPlayer = dependencies.resolve!Violin(ResolveOption.registerBeforeResolving);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* You can make the resolve option persistent by setting it on the container with setPersistentResolveOptions().
|
* You can make the resolve option persistent by setting it on the container with setPersistentResolveOptions().
|
||||||
|
|
|
@ -140,7 +140,7 @@ private void autowireMember(string member, size_t memberIndex, Type)(shared(Depe
|
||||||
static if (isDynamicArray!MemberType) {
|
static if (isDynamicArray!MemberType) {
|
||||||
alias MemberElementType = ElementType!MemberType;
|
alias MemberElementType = ElementType!MemberType;
|
||||||
static if (isOptional) {
|
static if (isOptional) {
|
||||||
auto instances = container.resolveAll!MemberElementType([ResolveOption.noResolveException]);
|
auto instances = container.resolveAll!MemberElementType(ResolveOption.noResolveException);
|
||||||
} else {
|
} else {
|
||||||
auto instances = container.resolveAll!MemberElementType;
|
auto instances = container.resolveAll!MemberElementType;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ private QualifierType createOrResolveInstance(MemberType, QualifierType, bool cr
|
||||||
return cast(MemberType) instanceFactory.getInstance();
|
return cast(MemberType) instanceFactory.getInstance();
|
||||||
} else {
|
} else {
|
||||||
static if (isOptional) {
|
static if (isOptional) {
|
||||||
return container.resolve!(MemberType, QualifierType)([ResolveOption.noResolveException]);
|
return container.resolve!(MemberType, QualifierType)(ResolveOption.noResolveException);
|
||||||
} else {
|
} else {
|
||||||
return container.resolve!(MemberType, QualifierType);
|
return container.resolve!(MemberType, QualifierType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,36 +47,38 @@ class RegistrationException : Exception {
|
||||||
* Options which influence the process of registering dependencies
|
* 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
|
* Prevent a concrete type being registered on itself. With this option you will always need
|
||||||
* to use the supertype as the type of the dependency.
|
* to use the supertype as the type of the dependency.
|
||||||
*/
|
*/
|
||||||
doNotAddConcreteTypeRegistration,
|
doNotAddConcreteTypeRegistration = 1,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent a concrete type being registered on itself. With this option you will always need
|
* Prevent a concrete type being registered on itself. With this option you will always need
|
||||||
* to use the supertype as the type of the dependency.
|
* to use the supertype as the type of the dependency.
|
||||||
* @deprecated use doNotAddConcreteTypeRegistration instead
|
* @deprecated use doNotAddConcreteTypeRegistration instead
|
||||||
*/
|
*/
|
||||||
DO_NOT_ADD_CONCRETE_TYPE_REGISTRATION
|
DO_NOT_ADD_CONCRETE_TYPE_REGISTRATION = doNotAddConcreteTypeRegistration
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options which influence the process of resolving dependencies
|
* 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.
|
* Registers the type you're trying to resolve before returning it.
|
||||||
* This essentially makes registration optional for resolving by concerete types.
|
* This essentially makes registration optional for resolving by concerete types.
|
||||||
* Resolinvg will still fail when trying to resolve a dependency by supertype.
|
* Resolinvg will still fail when trying to resolve a dependency by supertype.
|
||||||
*/
|
*/
|
||||||
registerBeforeResolving,
|
registerBeforeResolving = 1 << 0,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does not throw a resolve exception when a type is not registered but will
|
* Does not throw a resolve exception when a type is not registered but will
|
||||||
* return null instead. If the type is an array, an empty array is returned instead.
|
* return null instead. If the type is an array, an empty array is returned instead.
|
||||||
*/
|
*/
|
||||||
noResolveException
|
noResolveException = 1 << 1
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,8 +96,8 @@ synchronized class DependencyContainer {
|
||||||
|
|
||||||
private Registration[] autowireStack;
|
private Registration[] autowireStack;
|
||||||
|
|
||||||
private RegistrationOption[] persistentRegistrationOptions;
|
private RegistrationOption persistentRegistrationOptions;
|
||||||
private ResolveOption[] persistentResolveOptions;
|
private ResolveOption persistentResolveOptions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a dependency by concrete class type.
|
* Register a dependency by concrete class type.
|
||||||
|
@ -117,15 +119,27 @@ synchronized class DependencyContainer {
|
||||||
*
|
*
|
||||||
* See_Also: singleInstance, newInstance, existingInstance
|
* See_Also: singleInstance, newInstance, existingInstance
|
||||||
*/
|
*/
|
||||||
public Registration register(ConcreteType)(RegistrationOption[] options = []) {
|
public Registration register(ConcreteType)(RegistrationOption options = RegistrationOption.none) {
|
||||||
return register!(ConcreteType, ConcreteType)(options);
|
return register!(ConcreteType, ConcreteType)(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deprecated: Use register(SuperType, ConcreteType)(RegistrationOption[]) instead
|
* Deprecated: Use register(ConcreteType)(RegistrationOptions) instead.
|
||||||
*/
|
*/
|
||||||
public Registration register(SuperType, ConcreteType : SuperType)(RegistrationOption[] options...) {
|
deprecated public Registration register(ConcreteType)(RegistrationOption[] options) {
|
||||||
return register!(SuperType, ConcreteType)(options);
|
return register!(ConcreteType)(buildFlags(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: Use register(SuperType, ConcreteType)(RegistrationOptions) instead
|
||||||
|
*/
|
||||||
|
deprecated public Registration register(SuperType, ConcreteType : SuperType)(RegistrationOption first, RegistrationOption[] options...) {
|
||||||
|
return register!(SuperType, ConcreteType)(first | buildFlags(options));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
deprecated public Registration register(SuperType, ConcreteType : SuperType)(RegistrationOption[] options) {
|
||||||
|
return register!(SuperType, ConcreteType)(buildFlags(options));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -145,7 +159,7 @@ synchronized class DependencyContainer {
|
||||||
*
|
*
|
||||||
* See_Also: singleInstance, newInstance, existingInstance, RegistrationOption
|
* See_Also: singleInstance, newInstance, existingInstance, RegistrationOption
|
||||||
*/
|
*/
|
||||||
public Registration register(SuperType, ConcreteType : SuperType)(RegistrationOption[] options = []) {
|
public Registration register(SuperType, ConcreteType : SuperType)(RegistrationOption options = RegistrationOption.none) {
|
||||||
TypeInfo registeredType = typeid(SuperType);
|
TypeInfo registeredType = typeid(SuperType);
|
||||||
TypeInfo_Class concreteType = typeid(ConcreteType);
|
TypeInfo_Class concreteType = typeid(ConcreteType);
|
||||||
|
|
||||||
|
@ -161,8 +175,8 @@ synchronized class DependencyContainer {
|
||||||
auto newRegistration = new AutowiredRegistration!ConcreteType(registeredType, this);
|
auto newRegistration = new AutowiredRegistration!ConcreteType(registeredType, this);
|
||||||
newRegistration.singleInstance();
|
newRegistration.singleInstance();
|
||||||
|
|
||||||
if (!hasOption(options, persistentRegistrationOptions, RegistrationOption.doNotAddConcreteTypeRegistration)) {
|
static if (!is(SuperType == ConcreteType)) {
|
||||||
static if (!is(SuperType == ConcreteType)) {
|
if (!hasOption(options, persistentRegistrationOptions, RegistrationOption.doNotAddConcreteTypeRegistration)) {
|
||||||
auto concreteTypeRegistration = register!ConcreteType;
|
auto concreteTypeRegistration = register!ConcreteType;
|
||||||
concreteTypeRegistration.linkTo(newRegistration);
|
concreteTypeRegistration.linkTo(newRegistration);
|
||||||
}
|
}
|
||||||
|
@ -172,34 +186,16 @@ synchronized class DependencyContainer {
|
||||||
return newRegistration;
|
return newRegistration;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool hasOption(OptionType)(OptionType[] options, shared(OptionType[]) persistentOptions, OptionType option) {
|
private bool hasOption(OptionType)(OptionType options, OptionType persistentOptions, OptionType option) {
|
||||||
foreach (presentOption; persistentOptions) {
|
return ((options | persistentOptions) & option) != 0;
|
||||||
static if (is(OptionType == RegistrationOption)) {
|
}
|
||||||
// DEPRECATED LEGACY COMPATIBILITY - REMOVE REMOVE REMOVE REMOVE REMOVE REMOVE (SOON)
|
|
||||||
if (presentOption == RegistrationOption.DO_NOT_ADD_CONCRETE_TYPE_REGISTRATION) {
|
|
||||||
presentOption = RegistrationOption.doNotAddConcreteTypeRegistration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presentOption == option) {
|
private OptionType buildFlags(OptionType)(OptionType[] options) {
|
||||||
return true;
|
OptionType flags;
|
||||||
}
|
foreach (option; options) {
|
||||||
|
flags |= option;
|
||||||
}
|
}
|
||||||
|
return flags;
|
||||||
foreach(presentOption ; options) {
|
|
||||||
static if (is(OptionType == RegistrationOption)) {
|
|
||||||
// DEPRECATED LEGACY COMPATIBILITY - REMOVE REMOVE REMOVE REMOVE REMOVE REMOVE (SOON)
|
|
||||||
if (presentOption == RegistrationOption.DO_NOT_ADD_CONCRETE_TYPE_REGISTRATION) {
|
|
||||||
presentOption = RegistrationOption.doNotAddConcreteTypeRegistration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (presentOption == option) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Registration getExistingRegistration(TypeInfo registrationType, TypeInfo qualifierType) {
|
private Registration getExistingRegistration(TypeInfo registrationType, TypeInfo qualifierType) {
|
||||||
|
@ -260,10 +256,24 @@ synchronized class DependencyContainer {
|
||||||
* ---
|
* ---
|
||||||
* You need to use the resolve method which allows you to specify a qualifier.
|
* You need to use the resolve method which allows you to specify a qualifier.
|
||||||
*/
|
*/
|
||||||
public RegistrationType resolve(RegistrationType)(ResolveOption[] resolveOptions = []) {
|
public RegistrationType resolve(RegistrationType)(ResolveOption resolveOptions = ResolveOption.none) {
|
||||||
return resolve!(RegistrationType, RegistrationType)(resolveOptions);
|
return resolve!(RegistrationType, RegistrationType)(resolveOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: Use register(RegistrationType)(ResolveOption) instead.
|
||||||
|
*/
|
||||||
|
deprecated public RegistrationType resolve(RegistrationType)(ResolveOption[] resolveOptions) {
|
||||||
|
return resolve!(RegistrationType)(buildFlags(resolveOptions));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: Use register(RegistrationType, QualifierType)(ResolveOption) instead.
|
||||||
|
*/
|
||||||
|
deprecated public QualifierType resolve(RegistrationType, QualifierType : RegistrationType)(ResolveOption[] resolveOptions) {
|
||||||
|
return resolve!(RegistrationType, QualifierType)(buildFlags(resolveOptions));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve dependencies using a qualifier.
|
* Resolve dependencies using a qualifier.
|
||||||
*
|
*
|
||||||
|
@ -290,7 +300,7 @@ synchronized class DependencyContainer {
|
||||||
* container.resolve!(Animal, Dog);
|
* container.resolve!(Animal, Dog);
|
||||||
* ---
|
* ---
|
||||||
*/
|
*/
|
||||||
public QualifierType resolve(RegistrationType, QualifierType : RegistrationType)(ResolveOption[] resolveOptions = []) {
|
public QualifierType resolve(RegistrationType, QualifierType : RegistrationType)(ResolveOption resolveOptions = ResolveOption.none) {
|
||||||
TypeInfo resolveType = typeid(RegistrationType);
|
TypeInfo resolveType = typeid(RegistrationType);
|
||||||
TypeInfo qualifierType = typeid(QualifierType);
|
TypeInfo qualifierType = typeid(QualifierType);
|
||||||
|
|
||||||
|
@ -348,7 +358,7 @@ synchronized class DependencyContainer {
|
||||||
* Animal[] animals = container.resolveAll!Animal;
|
* Animal[] animals = container.resolveAll!Animal;
|
||||||
* ---
|
* ---
|
||||||
*/
|
*/
|
||||||
public RegistrationType[] resolveAll(RegistrationType)(ResolveOption[] resolveOptions = []) {
|
public RegistrationType[] resolveAll(RegistrationType)(ResolveOption resolveOptions = ResolveOption.none) {
|
||||||
RegistrationType[] instances;
|
RegistrationType[] instances;
|
||||||
TypeInfo resolveType = typeid(RegistrationType);
|
TypeInfo resolveType = typeid(RegistrationType);
|
||||||
|
|
||||||
|
@ -368,6 +378,13 @@ synchronized class DependencyContainer {
|
||||||
return instances;
|
return instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deprecated: Use resolveAll(RegistrationType)(ResolveOptions) instead.
|
||||||
|
*/
|
||||||
|
deprecated public RegistrationType[] resolveAll(RegistrationType)(ResolveOption[] resolveOptions) {
|
||||||
|
return resolveAll!RegistrationType(buildFlags(resolveOptions));
|
||||||
|
}
|
||||||
|
|
||||||
private Registration getQualifiedRegistration(TypeInfo resolveType, TypeInfo qualifierType, Registration[] candidates) {
|
private Registration getQualifiedRegistration(TypeInfo resolveType, TypeInfo qualifierType, Registration[] candidates) {
|
||||||
if (resolveType == qualifierType) {
|
if (resolveType == qualifierType) {
|
||||||
if (candidates.length > 1) {
|
if (candidates.length > 1) {
|
||||||
|
@ -431,35 +448,39 @@ synchronized class DependencyContainer {
|
||||||
/**
|
/**
|
||||||
* Apply persistent registration options which will be used everytime register() is called.
|
* Apply persistent registration options which will be used everytime register() is called.
|
||||||
*/
|
*/
|
||||||
public void setPersistentRegistrationOptions(OptionsTuple...)(OptionsTuple registrationOptions) {
|
public void setPersistentRegistrationOptions(RegistrationOption[] registrationOptions...) {
|
||||||
unsetPersistentRegistrationOptions();
|
persistentRegistrationOptions = buildFlags(registrationOptions);
|
||||||
foreach (option; registrationOptions) {
|
}
|
||||||
persistentRegistrationOptions ~= option;
|
|
||||||
}
|
/// ditto
|
||||||
|
public void setPersistentRegistrationOptions(RegistrationOption options) {
|
||||||
|
persistentRegistrationOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsets all applied registration options
|
* Unsets all applied registration options
|
||||||
*/
|
*/
|
||||||
public void unsetPersistentRegistrationOptions() {
|
public void unsetPersistentRegistrationOptions() {
|
||||||
persistentRegistrationOptions = [];
|
persistentRegistrationOptions = RegistrationOption.none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply persistent resolve options which will be used everytime resolve() is called.
|
* Apply persistent resolve options which will be used everytime resolve() is called.
|
||||||
*/
|
*/
|
||||||
public void setPersistentResolveOptions(OptionsTuple...)(OptionsTuple resolveOptions) {
|
public void setPersistentResolveOptions(ResolveOption[] resolveOptions...) {
|
||||||
unsetPersistentResolveOptions();
|
persistentResolveOptions = buildFlags(resolveOptions);
|
||||||
foreach (option; resolveOptions) {
|
}
|
||||||
persistentResolveOptions ~= option;
|
|
||||||
}
|
/// ditto
|
||||||
|
public void setPersistentResolveOptions(ResolveOption options) {
|
||||||
|
persistentResolveOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsets all applied registration options
|
* Unsets all applied registration options
|
||||||
*/
|
*/
|
||||||
public void unsetPersistentResolveOptions() {
|
public void unsetPersistentResolveOptions() {
|
||||||
persistentResolveOptions = [];
|
persistentResolveOptions = ResolveOption.none;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -497,7 +497,7 @@ version(unittest) {
|
||||||
// Test registering type with option doNotAddConcreteTypeRegistration
|
// Test registering type with option doNotAddConcreteTypeRegistration
|
||||||
unittest {
|
unittest {
|
||||||
shared(DependencyContainer) container = new DependencyContainer();
|
shared(DependencyContainer) container = new DependencyContainer();
|
||||||
container.register!(TestInterface, TestClass)([RegistrationOption.doNotAddConcreteTypeRegistration]);
|
container.register!(TestInterface, TestClass)(RegistrationOption.doNotAddConcreteTypeRegistration);
|
||||||
|
|
||||||
auto firstInstance = container.resolve!TestInterface;
|
auto firstInstance = container.resolve!TestInterface;
|
||||||
assertThrown!ResolveException(container.resolve!TestClass);
|
assertThrown!ResolveException(container.resolve!TestClass);
|
||||||
|
@ -506,7 +506,7 @@ version(unittest) {
|
||||||
// Test registering type with option DO_NOT_ADD_CONCRETE_TYPE_REGISTRATION (DEPRECATED)
|
// Test registering type with option DO_NOT_ADD_CONCRETE_TYPE_REGISTRATION (DEPRECATED)
|
||||||
unittest {
|
unittest {
|
||||||
shared(DependencyContainer) container = new DependencyContainer();
|
shared(DependencyContainer) container = new DependencyContainer();
|
||||||
container.register!(TestInterface, TestClass)([RegistrationOption.DO_NOT_ADD_CONCRETE_TYPE_REGISTRATION]);
|
container.register!(TestInterface, TestClass)(RegistrationOption.DO_NOT_ADD_CONCRETE_TYPE_REGISTRATION);
|
||||||
|
|
||||||
auto firstInstance = container.resolve!TestInterface;
|
auto firstInstance = container.resolve!TestInterface;
|
||||||
assertThrown!ResolveException(container.resolve!TestClass);
|
assertThrown!ResolveException(container.resolve!TestClass);
|
||||||
|
@ -515,7 +515,7 @@ version(unittest) {
|
||||||
// Test registering conrete type with registration option doNotAddConcreteTypeRegistration does nothing
|
// Test registering conrete type with registration option doNotAddConcreteTypeRegistration does nothing
|
||||||
unittest {
|
unittest {
|
||||||
shared(DependencyContainer) container = new DependencyContainer();
|
shared(DependencyContainer) container = new DependencyContainer();
|
||||||
container.register!TestClass([RegistrationOption.doNotAddConcreteTypeRegistration]);
|
container.register!TestClass(RegistrationOption.doNotAddConcreteTypeRegistration);
|
||||||
container.resolve!TestClass;
|
container.resolve!TestClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -631,7 +631,7 @@ version(unittest) {
|
||||||
// Test registration when resolving
|
// Test registration when resolving
|
||||||
unittest {
|
unittest {
|
||||||
shared(DependencyContainer) container = new DependencyContainer();
|
shared(DependencyContainer) container = new DependencyContainer();
|
||||||
container.resolve!(TestInterface, TestClass)([ResolveOption.registerBeforeResolving]);
|
container.resolve!(TestInterface, TestClass)(ResolveOption.registerBeforeResolving);
|
||||||
container.resolve!TestClass;
|
container.resolve!TestClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,20 +653,20 @@ version(unittest) {
|
||||||
// Test ResolveOption registerBeforeResolving fails for interfaces
|
// Test ResolveOption registerBeforeResolving fails for interfaces
|
||||||
unittest {
|
unittest {
|
||||||
shared(DependencyContainer) container = new DependencyContainer();
|
shared(DependencyContainer) container = new DependencyContainer();
|
||||||
assertThrown!ResolveException(container.resolve!TestInterface([ResolveOption.registerBeforeResolving]));
|
assertThrown!ResolveException(container.resolve!TestInterface(ResolveOption.registerBeforeResolving));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test ResolveOption noResolveException does not throw
|
// Test ResolveOption noResolveException does not throw
|
||||||
unittest {
|
unittest {
|
||||||
shared(DependencyContainer) container = new DependencyContainer();
|
shared(DependencyContainer) container = new DependencyContainer();
|
||||||
auto instance = container.resolve!TestInterface([ResolveOption.noResolveException]);
|
auto instance = container.resolve!TestInterface(ResolveOption.noResolveException);
|
||||||
assert(instance is null);
|
assert(instance is null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveOption noResolveException does not throw for resolveAll
|
// ResolveOption noResolveException does not throw for resolveAll
|
||||||
unittest {
|
unittest {
|
||||||
shared(DependencyContainer) container = new DependencyContainer();
|
shared(DependencyContainer) container = new DependencyContainer();
|
||||||
auto instances = container.resolveAll!TestInterface([ResolveOption.noResolveException]);
|
auto instances = container.resolveAll!TestInterface(ResolveOption.noResolveException);
|
||||||
assert(instances.length == 0);
|
assert(instances.length == 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue