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); }
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 static ReadOnlyCollection <IInstanceCreator> GetCreators(Type baseType) { return(TypeCreator.GetInstanceCreators(baseType)); }