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 GetOpenGenericArguments_returns_expected_number_of_arguments_for_type(Type type, int expectedCount) { var arguments = GenericTypeResolver.GetOpenGenericArguments(type); Assert.NotNull(arguments); Assert.Equal(expectedCount, arguments.Count); }
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); }
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); }
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); }
private static BindingCollection GetConcreteTypeBindings(Type type, LinkList <Binding> bindings, out LinkList <Type> openArguments) { Debug.Assert(type != null); Debug.Assert(bindings != null); // Avoid recursive searches for generic type. if (type.ContainsGenericParameters) { if (Binding.ContainsType(bindings, type)) { openArguments = LinkList <Type> .Empty; return(new BindingCollection( )); } bindings = bindings.Add(new Binding(null, type)); } // Bind all unassigned generic argument on the generic type. openArguments = GenericTypeResolver.GetOpenGenericArguments(type); var collection = new BindingCollection(bindings); GenericTypeResolver.BindGenericArguments(collection, openArguments); return(collection); }
public static MethodInfo MakeConcreteMethod(MethodInfo method, LinkList <Binding> bindings) { var openArguments = GenericTypeResolver.GetOpenGenericArguments(method.GetGenericArguments( )); return(GenericTypeResolver.MakeConcreteMethod(method, openArguments, bindings)); }
public static Type MakeConcreteType(Type genericType, LinkList <Binding> bindings) { var openArguments = GenericTypeResolver.GetOpenGenericArguments(genericType); return(GenericTypeResolver.MakeConcreteType(genericType, openArguments, bindings)); }
/// <summary> /// Returns all unassigned generic arguments on the <paramref name="genericType"/>. /// </summary> public static LinkList <Type> GetOpenGenericArguments(Type genericType) { return(GenericTypeResolver.GetOpenGenericArguments(genericType.GetGenericArguments( ))); }