private static IEnumerable <IInstanceCreator> GetGenericCreators(Type targetType, Type genericType)
        {
            Debug.Assert(targetType != null);
            Debug.Assert(genericType != null);
            Debug.Assert(genericType.ContainsGenericParameters);

            // Get all bindings for the generic type's arguments that satisfy the inheritance constraint.
            var openArguments = GenericTypeResolver.GetOpenGenericArguments(genericType);

            Assembly[]            referenceAssemblies;
            LinkList <Constraint> inheritanceConstraints =
                targetType.IsGenericParameter
                    ? Constraint.GetConstraints(targetType, out referenceAssemblies)
                    : Constraint.GetInheritanceConstraint(targetType).MakeLinkList( );
            var argumentBindings = new BindingCollection(Binding.EmptyBindings);

            Constraint.SatisfyConstraints(argumentBindings, genericType, inheritanceConstraints);

            // Construct concrete types for each set of argument bindings,
            //  and return the creators for each concrete type.
            var creators =
                from arguments in argumentBindings
                let concreteType = GenericTypeResolver.CreateConcreteType(genericType, openArguments, arguments)
                                   where concreteType != null
                                   from creator in TypeCreator.GetInstanceCreators(targetType, concreteType)
                                   select creator;

            return(creators);
        }
        public void CreateConcreteType_returns_null_for_generic_type_with_partial_bindings( )
        {
            Type type          = typeof(IDictionary <,>);
            var  openArguments = GenericTypeResolver.GetOpenGenericArguments(type);
            var  bindings      = Binding.EmptyBindings.Add(new Binding(openArguments.Value, typeof(int)));

            var concreteType = GenericTypeResolver.CreateConcreteType(type, openArguments, bindings);

            Assert.Null(concreteType);
        }
        public void CreateConcreteType_returns_null_for_generic_type_with_no_bindings( )
        {
            Type type          = typeof(Nullable <>);
            var  openArguments = GenericTypeResolver.GetOpenGenericArguments(type);
            var  bindings      = Binding.EmptyBindings;

            var concreteType = GenericTypeResolver.CreateConcreteType(type, openArguments, bindings);

            Assert.Null(concreteType);
        }
        public void CreateConcreteType_succeeds_for_concrete_type( )
        {
            Type type          = typeof(int);
            var  openArguments = GenericTypeResolver.GetOpenGenericArguments(type);
            var  bindings      = Binding.EmptyBindings;

            var concreteType = GenericTypeResolver.CreateConcreteType(type, openArguments, bindings);

            Assert.NotNull(concreteType);
            Assert.Equal(type, concreteType);
        }
        public void CreateConcreteType_succeeds_for_generic_type_with_duplicate_bindings( )
        {
            Type genericType   = typeof(Nullable <>);
            var  openArguments = GenericTypeResolver.GetOpenGenericArguments(genericType);
            var  bindings      = GetBindingList(new[] { new Binding(openArguments.Value, typeof(int)), new Binding(openArguments.Value, typeof(int)) });

            var concreteType = GenericTypeResolver.CreateConcreteType(genericType, openArguments, bindings);

            Assert.NotNull(concreteType);
            Assert.Equal(genericType, concreteType.GetGenericTypeDefinition( ));

            var constructedType = genericType.MakeGenericType(typeof(int));

            Assert.Equal(constructedType, concreteType);
        }
        public void CreateConcreteType_succeeds_for_generic_type_with_full_bindings(Type genericType)
        {
            var openArguments = GenericTypeResolver.GetOpenGenericArguments(genericType);
            var bindings      = GetBindingList(openArguments.Select((a, i) => new Binding(a, typeof(int))));

            var concreteType = GenericTypeResolver.CreateConcreteType(genericType, openArguments, bindings);

            Assert.NotNull(concreteType);
            Assert.Equal(genericType, concreteType.GetGenericTypeDefinition( ));

            Type[] typeArguments = new Type[bindings.Count];
            for (int i = 0; i < typeArguments.Length; ++i)
            {
                typeArguments[i] = typeof(int);
            }
            var constructedType = genericType.MakeGenericType(typeArguments);

            Assert.Equal(constructedType, concreteType);
        }