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));
 }