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);
        }
示例#17
0
        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);
        }