public void GetCreators_returns_expected_instances_from_factory_class( ) { var type = typeof(ClassFromFactory); var expectedInstanceTypes = new[] { type }; var creators = TypeCreator.GetCreators(type); TestCreators(type, expectedInstanceTypes, creators); }
public void GetCreators_returns_single_derived_type_for_abstract_class( ) { var type = typeof(AbstractBaseClass); var expectedInstanceTypes = new[] { typeof(DerivedSealedClass) }; var creators = TypeCreator.GetCreators(type); TestCreators(type, expectedInstanceTypes, creators); }
public void GetCreators_returns_single_derived_type_for_abstract_class_constrained_type_argument( ) { var type = typeof(AbstractBaseClassTypeParameter <>).GetGenericArguments( ).Single( ); var expectedInstanceTypes = new[] { typeof(DerivedSealedClass) }; var creators = TypeCreator.GetCreators(type); TestCreators(type, expectedInstanceTypes, creators); }
public void GetCreators_returns_all_derived_types_for_base_class( ) { var type = typeof(BaseClass); var expectedInstanceTypes = new[] { type, typeof(DerivedClass) }; var creators = TypeCreator.GetCreators(type); TestCreators(type, expectedInstanceTypes, creators); }
public void GetCreators_ignores_recursive_parameters( ) { var type = typeof(RecursiveClass); var expectedInstanceTypes = Type.EmptyTypes; var creators = TypeCreator.GetCreators(type); TestCreators(type, expectedInstanceTypes, creators); }
public void GetCreators_returns_expected_instances_for_generic_factory_taking_IInstanceCreator_argument( ) { Type targetType = typeof(ILazyGenericFactoryInterfaceWrapper <>); Type[] expectedInstanceTypes = new[] { typeof(LazyGenericFactoryInterfaceWrapperImpl <double>) }; var creators = TypeCreator.GetCreators(targetType); TestCreators(targetType, expectedInstanceTypes, creators); }
public void GetCreators_returns_expected_instances_for_generic_factory_method_returning_generic_type( ) { Type targetType = typeof(IGenericFactoryInterfaceWrapper <>); Type[] expectedInstanceTypes = new[] { typeof(GenericFactoryInterfaceWrapperImpl <double>) }; var creators = TypeCreator.GetCreators(targetType); TestCreators(targetType, expectedInstanceTypes, creators); }
public void GetCreators_returns_expected_instances_for_unconstrained_generic_type( ) { Type targetType = typeof(UnconstrainedGenericType <>); Type[] expectedInstanceTypes = new[] { typeof(UnconstrainedGenericType <bool>) }; var creators = TypeCreator.GetCreators(targetType); TestCreators(targetType, expectedInstanceTypes, creators); }
public void GetCreators_uses_instance_data_instantiator( ) { int current = InstantiateInstanceDataType.InvokeCount; var creators = TypeCreator.GetCreators(typeof(SealedStruct)); creators[0].CreateInstance( ); int actual = InstantiateInstanceDataType.InvokeCount; Assert.True(actual > current, typeof(InstantiateInstanceDataType).Name + " was not used by instance data creator: " + actual); }
public void GetCreators_returns_expected_instances_for_generic_factory_taking_partial_generic_argument( ) { Type targetType = typeof(PartialGenericArgumentWrapperImpl <>); Type[] expectedInstanceTypes = new[] { typeof(PartialGenericArgumentWrapperImpl <string>), typeof(PartialGenericArgumentWrapperImpl <int>) }; var creators = TypeCreator.GetCreators(targetType); TestCreators(targetType, expectedInstanceTypes, creators); }
public void GetCreators_returns_expected_instances_for_interface_implemented_by_generic_type( ) { Type targetType = typeof(ITargetInterface); Type[] expectedInstanceTypes = new[] { typeof(TargetInterfaceImpl <double, ParameterInterfaceImpl>) }; var creators = TypeCreator.GetCreators(targetType); TestCreators(targetType, expectedInstanceTypes, creators); }
public void GetCreators_returns_only_default_constructor_creator_for_types_with_too_many_parameterized_constructors(Type type) { var expectedInstanceTypes = new[] { type }; var creators = TypeCreator.GetCreators(type); TestCreators(type, expectedInstanceTypes, creators); var creator = Assert.Single(creators); Assert.NotNull(creator); }
private static IEnumerable <IInstanceCreator> GetMethodCreators(Type targetType, MethodBase method) { Debug.Assert(targetType != null); Debug.Assert(method != null); Debug.Assert(method.IsGenericMethod || !targetType.ContainsGenericParameters); // Ignore recursive parameters. var parameters = method.GetParameters( ); if (parameters.Any(p => p.ParameterType.Is(targetType) || p.ParameterType.Is(method.DeclaringType))) { yield break; } // Retrieve creators for each parameter. var availableArguments = parameters.Select((p) => TypeCreator.GetInstanceCreators(p.ParameterType).AsEnumerable( )); // Call constructor with all argument permutations. foreach (var arguments in Permuter.Permute(availableArguments)) { // If method is concrete, use it. if (!method.IsGenericMethod) { yield return(WeakInstanceCreator.ForMethod(targetType, method, arguments)); } // Otherwise, try to resolve generic arguments on method. else if (method is MethodInfo) { var methodInfo = (MethodInfo)method; var bindings = new BindingCollection(Binding.EmptyBindings); for (int i = 0; i < parameters.Length; ++i) { ParameterInfo parameter = parameters[i]; IInstanceCreator argument = arguments[i]; if (parameter.ParameterType.ContainsGenericParameters) { GenericTypeResolver.GetAssignedGenericArguments(bindings, argument.InstanceType, parameter.ParameterType); } } foreach (LinkList <Binding> b in bindings) { var concreteMethod = GenericTypeResolver.MakeConcreteMethod(methodInfo, b); if (concreteMethod != null) { targetType = concreteMethod.ReturnType; yield return(WeakInstanceCreator.ForMethod(targetType, concreteMethod, arguments)); } } } } }
public void GetCreators_returns_expected_instances_for_generic_method_argument_types(MethodInfo genericMethod) { var concreteMethods = GenericTypeResolver.GetConcreteMethods(genericMethod); foreach (var method in concreteMethods) { Type genericType = method.GetParameters( ).Single( ).ParameterType; var creators = TypeCreator.GetCreators(genericType); TestCreators(genericType, new[] { genericType }, creators); } }
public void GetCreators_returns_all_enum_values(Type enumType, object[] values) { var creators = TypeCreator.GetCreators(enumType); Assert.Equal(values.Length, creators.Count); foreach (var creator in creators) { Assert.Equal(enumType, creator.InstanceType); var value = creator.CreateInstance( ); Assert.Contains(value, values); } }
private static IEnumerable <IInstanceCreator> GetConstructorCreators(Type targetType, Type availableType) { Debug.Assert(targetType != null); Debug.Assert(availableType != null); Debug.Assert(!availableType.IsAbstract); if (targetType.ContainsGenericParameters) { Type definition = targetType.IsGenericParameter ? targetType : targetType.GetGenericTypeDefinition( ); var bindings = new BindingCollection(Binding.EmptyBindings); GenericTypeResolver.GetAssignedGenericArguments(bindings, availableType, definition); foreach (var binding in bindings) { Type resolvedType = definition.IsGenericParameter ? Binding.ForArgument(binding, definition).Type : GenericTypeResolver.MakeConcreteType(definition, binding); targetType = resolvedType; break; } } var creators = new List <IInstanceCreator>( ); // If type is an enumeration, get creator for enum values. if (availableType.IsEnum || availableType == typeof(bool)) { creators.AddRange(WeakInstanceCreator.ForEnum(availableType)); } // Otherwise, get creator for any default constructor. else if (Constraint.HasDefaultConstructor(availableType)) { creators.Add(WeakInstanceCreator.ForType(availableType)); } // Get creators for any parameterized constructors. var parameterizedConstructors = availableType.GetConstructors( ).Where((c) => c.GetParameters( ).Length > 0).ToArray( ); if (parameterizedConstructors.Length < 3) { foreach (var constructor in parameterizedConstructors) { creators.AddRange(TypeCreator.GetMethodCreators(targetType, constructor)); } } return(creators); }
public void GetConcreteMethods_succeeds_for_generic_method_with_multiple_resolutions( ) { const string methodName = "GenericMethod_MultipleFactoryResolutions"; var method = GetMethod(methodName); var concreteMethods = GenericTypeResolver.GetConcreteMethods(method) .ToArray( ); Assert.Equal(2, concreteMethods.Length); foreach (var concreteMethod in concreteMethods) { var parameter = concreteMethod.GetParameters( ).Single( ); var instances = TypeCreator.GetCreators(parameter.ParameterType); Assert.Equal(1, instances.Count); } }
private static ICollection <MethodInfo> GetConcreteMethods(MethodInfo method, LinkList <Binding> bindings) { Debug.Assert(method != null); Debug.Assert(bindings != null); // Try to resolve generic arguments on method. var openArguments = GenericTypeResolver.GetOpenGenericArguments(method.GetGenericArguments( )); var concreteBindings = new BindingCollection(bindings); GenericTypeResolver.BindGenericArguments(concreteBindings, openArguments); var concreteMethods = concreteBindings.Transform((b) => MakeConcreteMethod(method, openArguments, b)); // If generic arguments cannot be resolved statically, try to bind method arguments by searching for creatable parameter types. if (concreteMethods.Count == 0) { var genericParameterTypes = method.GetParameters( ) .Select(p => p.ParameterType) .Where(t => t.IsGenericType) .ToArray( ); Debug.Assert(genericParameterTypes.All(t => !t.IsGenericParameter)); var creatableParameterTypes = genericParameterTypes .Select(t => TypeCreator.GetCreators(t) .Select(c => c.InstanceType) .Distinct( ) ); var parameterBindings = new BindingCollection(bindings); parameterBindings.Expand(Permuter.Permute(creatableParameterTypes), (b, permutation) => { for (int i = 0; i < permutation.Length; ++i) { Type permutationType = permutation[i]; Type genericParameterType = genericParameterTypes[i]; GenericTypeResolver.GetAssignedGenericArguments(b, permutationType, genericParameterType); } }); concreteMethods = parameterBindings.Transform((b) => MakeConcreteMethod(method, openArguments, b)); } return(concreteMethods); }
private static ReadOnlyCollection <IInstanceCreator> GetInstanceCreators(Type targetType) { Debug.Assert(targetType != null); Debug.Assert(targetType.IsVisible); // If creators have not been cached, or are in the process of being cached, take lock and re-check cache. ReadOnlyCollection <IInstanceCreator> cached; if (!creatorCache_.TryGetValue(targetType, out cached) || object.ReferenceEquals(cached, TempCreators)) { bool isInstanceCreator = targetType.IsGenericType && targetType.GetGenericTypeDefinition( ) == typeof(IInstanceCreator <>); Type[] availableTypes = isInstanceCreator ? null : TypeLoader.GetUsableTypes(targetType).ToArray( ); lock ( creatorCacheLock_ ) { if (!TypeCreator.creatorCache_.ContainsKey(targetType)) { TypeCreator.creatorCache_[targetType] = TempCreators; ReadOnlyCollection <IInstanceCreator> creators; // If target type is for IInstanceCreator<T>, wrap creators for T. if (isInstanceCreator) { Type innerTargetType = targetType.GetGenericArguments( )[0]; var innerCreators = TypeCreator.GetCreators(innerTargetType); var outerCreators = new IInstanceCreator[innerCreators.Count]; for (int i = 0; i < outerCreators.Length; ++i) { outerCreators[i] = WeakInstanceCreator.ForInstanceCreator(targetType, innerCreators[i]); } creators = outerCreators.ToReadOnlyCollection( ); } // Otherwise, get creators for type directly. else { creators = GetInstanceCreators(targetType, availableTypes); } TypeCreator.creatorCache_[targetType] = creators; } } } return(TypeCreator.creatorCache_[targetType]); }
public void GetCreators_returns_expected_instances_for_generic_types(Type genericType, Type[] expectedInstanceTypes) { Type[] arguments = new Type[genericType.GetGenericArguments( ).Length]; if (arguments.Length > 2) { return; } arguments[0] = typeof(double); for (int i = 0; i < expectedInstanceTypes.Length; ++i) { arguments[arguments.Length - 1] = expectedInstanceTypes[i]; expectedInstanceTypes[i] = genericType.MakeGenericType(arguments); } var creators = TypeCreator.GetCreators(genericType); TestCreators(genericType, expectedInstanceTypes, creators); }
public void GetCreators_returns_expected_instances_for_generic_IInstanceCreator(Type innerTargetType) { Type targetType = typeof(IInstanceCreator <>).MakeGenericType(innerTargetType); var innerCreators = TypeCreator.GetCreators(innerTargetType); var creators = TypeCreator.GetCreators(targetType); Assert.NotNull(creators); Assert.NotNull(innerCreators); Assert.Equal(innerCreators.Count, creators.Count); foreach (var creator in creators) { Assert.True(creator.InstanceType.Is(typeof(IInstanceCreator))); var inner = (IInstanceCreator)creator.CreateInstance( ); Assert.True(inner.InstanceType.Is(innerTargetType)); } }
public void GetCreators_returns_expected_instances_for_generic_type_with_multiple_resolutions(Type genericType, Type[] expectedInstanceTypes) { var creators = TypeCreator.GetCreators(genericType); TestCreators(genericType, expectedInstanceTypes, creators); }
public void GetCreators_returns_expected_instances_for_generic_type_with_constructor_parameters(Type type, Type[] expectedInstanceTypes) { var creators = TypeCreator.GetCreators(type); TestCreators(type, expectedInstanceTypes, creators); }
public static ReadOnlyCollection <IInstanceCreator> GetCreators(Type baseType) { return(TypeCreator.GetInstanceCreators(baseType)); }
public void GetCreators_returns_empty_collection_for_assembly_excluded_type( ) { var creators = TypeCreator.GetCreators(typeof(AssemblyExcludedType)); Assert.Empty(creators); }