Ejemplo n.º 1
0
        internal GenericTypeBuilder(Type closedGenericBaseType, Type openGenericImplementation)
        {
            this.closedGenericBaseType = closedGenericBaseType;

            this.openGenericImplementation = openGenericImplementation;

            if (openGenericImplementation.Info().IsGenericType && 
                !openGenericImplementation.Info().IsGenericTypeDefinition)
            {
                this.openGenericImplementation = openGenericImplementation.GetGenericTypeDefinition();
                this.partialOpenGenericImplementation = openGenericImplementation;
                this.isPartialOpenGenericImplementation = true;
            }
        }
Ejemplo n.º 2
0
        // This method takes generic type and returns a 'partially' generic type definition of that same type,
        // where all generic arguments up to the given nesting level. This allows us to group generic types
        // by their partial generic type definition, which allows a much nicer user experience.
        internal static Type MakeTypePartiallyGenericUpToLevel(Type type, int nestingLevel)
        {
            if (nestingLevel > 100)
            {
                // Stack overflow prevention
                throw new ArgumentException("nesting level bigger than 100 too high. Type: " +
                    type.ToFriendlyName(), nameof(nestingLevel));
            }

            // example given type: IEnumerable<IQueryProcessor<MyQuery<Alpha>, int[]>>
            // nestingLevel 4 returns: IEnumerable<IQueryHandler<MyQuery<Alpha>, int[]>
            // nestingLevel 3 returns: IEnumerable<IQueryHandler<MyQuery<Alpha>, int[]>
            // nestingLevel 2 returns: IEnumerable<IQueryHandler<MyQuery<T>, int[]>
            // nestingLevel 1 returns: IEnumerable<IQueryHandler<TQuery, TResult>>
            // nestingLevel 0 returns: IEnumerable<T>
            if (!type.Info().IsGenericType)
            {
                return type;
            }

            if (nestingLevel == 0)
            {
                return type.GetGenericTypeDefinition();
            }

            return MakeTypePartiallyGeneric(type, nestingLevel);
        }
        internal static PropertyInfo[] GetCandidateInjectionPropertiesFor(Type implementationType)
        {
            var all = BindingFlags.FlattenHierarchy |
                BindingFlags.Instance | BindingFlags.Static |
                BindingFlags.NonPublic | BindingFlags.Public;

            return implementationType.Info().GetProperties(all);
        }
        private ContainerControlledItem[] GetClosedContainerControlledItemsFor(Type serviceType)
        {
            var items = this.GetItemsFor(serviceType);

            return serviceType.Info().IsGenericType
                ? Helpers.GetClosedGenericImplementationsFor(serviceType, items)
                : items.ToArray();
        }
        private InstanceProducer[] GetAssignableProducers(Type closedServiceType)
        {
            var producers =
                from registrationGroup in this.RegistrationGroups
                where closedServiceType.Info().IsAssignableFrom(registrationGroup.ServiceType)
                select registrationGroup.UncontrolledProducer;

            return producers.ToArray();
        }
 public GenericArgumentFinder(Type serviceTypeDefinition, Type serviceTypeToResolve,
     Type implementationTypeDefinition, Type partialOpenGenericImplementation)
 {
     this.serviceTypeDefinitionArguments = serviceTypeDefinition.Info().GetGenericArguments();
     this.serviceTypeToResolveArguments = serviceTypeToResolve.Info().GetGenericArguments();
     this.implementationTypeDefinitionArguments = implementationTypeDefinition.Info().GetGenericArguments();
     this.partialImplementationArguments =
         (partialOpenGenericImplementation ?? implementationTypeDefinition).Info().GetGenericArguments();
 }
Ejemplo n.º 7
0
        private static Type MakeTypePartiallyGeneric(Type type, int nestingLevel)
        {
            var arguments = (
                from argument in type.Info().GetGenericArguments()
                select MakeTypePartiallyGenericUpToLevel(argument, nestingLevel - 1))
                .ToArray();

            try
            {
                return type.GetGenericTypeDefinition().MakeGenericType(arguments.ToArray());
            }
            catch (ArgumentException)
            {
                // If we come here, MakeGenericType failed because of generic type constraints.
                // In that case we skip this nesting level and go one level deeper.
                return MakeTypePartiallyGenericUpToLevel(type, nestingLevel + 1);
            }
        }
        private static ConstructorInfo GetSinglePublicConstructor(Type implementationType)
        {
            var constructors = implementationType.Info().GetConstructors();

            if (!constructors.Any())
            {
                throw new ActivationException(
                    StringResources.TypeMustHaveASinglePublicConstructorButItHasNone(implementationType));
            }

            if (constructors.Length > 1)
            {
                throw new ActivationException(
                    StringResources.TypeMustHaveASinglePublicConstructorButItHas(implementationType,
                        constructors.Length));
            }

            return constructors[0];
        }
Ejemplo n.º 9
0
 internal static string MixingRegistrationsWithControlledAndUncontrolledIsNotSupported(Type serviceType,
     bool controlled) => 
     string.Format(CultureInfo.InvariantCulture,
         "You already made a registration for the {0} type using one of the {3} " +
         "overloads that registers container-{1} collections, while this method registers container-" +
         "{2} collections. Mixing calls is not supported. Consider merging those calls or make both " +
         "calls either as controlled or uncontrolled registration.",
         (serviceType.Info().IsGenericType ? serviceType.GetGenericTypeDefinition() : serviceType).ToFriendlyName(),
         controlled ? "uncontrolled" : "controlled",
         controlled ? "controlled" : "uncontrolled",
         nameof(Container.RegisterCollection));
Ejemplo n.º 10
0
 internal static string SuppliedTypeDoesNotInheritFromOrImplement(Type service, Type implementation) => 
     string.Format(CultureInfo.InvariantCulture,
         "The supplied type {0} does not {1} {2}.",
         implementation.ToFriendlyName(),
         service.Info().IsInterface ? "implement" : "inherit from",
         service.ToFriendlyName());
Ejemplo n.º 11
0
 internal static string SuppliedElementDoesNotInheritFromOrImplement(Type serviceType, Type elementType,
     string elementDescription) =>
     string.Format(CultureInfo.InvariantCulture,
         "The supplied {0} of type {1} does not {2} {3}.",
         elementDescription,
         elementType.ToFriendlyName(),
         serviceType.Info().IsInterface ? "implement" : "inherit from",
         serviceType.ToFriendlyName());
Ejemplo n.º 12
0
 internal static IRegistrationEntry Create(Type serviceType, Container container) =>
     serviceType.Info().IsGenericType
         ? (IRegistrationEntry)new GenericRegistrationEntry(container)
         : (IRegistrationEntry)new NonGenericRegistrationEntry(serviceType, container);
Ejemplo n.º 13
0
        private static IEnumerable<Type> GetNestedTypeArgumentsForTypeArgument(Type argument, IList<Type> processedArguments)
        {
            processedArguments.Add(argument);

            if (argument.IsGenericParameter)
            {
                var nestedArguments =
                    from constraint in argument.Info().GetGenericParameterConstraints()
                    from arg in GetNestedTypeArgumentsForTypeArgument(constraint, processedArguments)
                    select arg;

                return nestedArguments.Concat(new[] { argument });
            }

            if (!argument.Info().IsGenericType)
            {
                return Enumerable.Empty<Type>();
            }

            return
                from genericArgument in argument.GetGenericArguments().Except(processedArguments)
                from arg in GetNestedTypeArgumentsForTypeArgument(genericArgument, processedArguments)
                select arg;
        }
Ejemplo n.º 14
0
        private CandicateServiceType ToCandicateServiceType(Type openCandidateServiceType)
        {
            if (openCandidateServiceType.Info().IsGenericType)
            {
                return new CandicateServiceType(openCandidateServiceType,
                    this.GetMatchingGenericArgumentsForOpenImplementationBasedOn(openCandidateServiceType));
            }

            return new CandicateServiceType(openCandidateServiceType, Helpers.Array<Type>.Empty);
        }
 private static bool IsPublicInternal(Type type)
 {
     return
         (type.IsNested ? type.Info().IsNestedPublic : type.Info().IsPublic) &&
         (!type.Info().IsGenericType || type.GetGenericArguments().All(IsPublic));
 }
Ejemplo n.º 16
0
 private static IEnumerable<Type> GetNestedTypeArgumentsForType(Type type) => (
     from argument in type.Info().GetGenericArguments()
     from nestedArgument in GetNestedTypeArgumentsForTypeArgument(argument, new List<Type>())
     select nestedArgument)
     .Distinct()
     .ToArray();
 private DiagnosticGroup BuildDiagnosticGroup(Type groupType, IEnumerable<DiagnosticResult> results, 
     int level) => 
     groupType.Info().ContainsGenericParameters
         ? this.BuildGenericGroup(groupType, results, level)
         : this.BuildNonGenericGroup(groupType, results);
Ejemplo n.º 18
0
        private Type GetDecoratorTypeFromDecoratorFactory(Type requestedServiceType, 
            DecoratorPredicateContext context)
        {
            Type decoratorType = this.data.DecoratorTypeFactory(context);

            if (decoratorType.Info().ContainsGenericParameters)
            {
                if (!requestedServiceType.Info().IsGenericType)
                {
                    throw new ActivationException(
                        StringResources.TheDecoratorReturnedFromTheFactoryShouldNotBeOpenGeneric(
                            requestedServiceType, decoratorType));
                }

                Requires.TypeFactoryReturnedTypeThatDoesNotContainUnresolvableTypeArguments(
                    requestedServiceType, decoratorType);

                var builder = new GenericTypeBuilder(requestedServiceType, decoratorType);

                decoratorType = builder.BuildClosedGenericImplementation().ClosedGenericImplementation;

                // decoratorType == null when type constraints don't match.
                if (decoratorType != null)
                {
                    Requires.HasFactoryCreatedDecorator(this.data.Container, requestedServiceType, decoratorType);
                }
            }
            else
            {
                Requires.FactoryReturnsATypeThatIsAssignableFromServiceType(requestedServiceType, decoratorType);
            }

            return decoratorType;
        }
        private ArgumentMapping[] ConvertToOpenImplementationArgumentMappingsForType(
           ArgumentMapping mapping, Type type, IList<Type> processedTypes)
        {
            var arguments = mapping.Argument.Info().GetGenericArguments();
            var concreteTypes = type.Info().GetGenericArguments();

            if (concreteTypes.Length != arguments.Length)
            {
                // The length of the concrete list and the generic argument list does not match. This normally
                // means that the generic argument contains a argument that is not generic (so Int32 instead
                // of T). In that case we can ignore everything, because the type will be unusable.
                return Helpers.Array<ArgumentMapping>.Empty;
            }

            return (
                from subMapping in ArgumentMapping.Zip(arguments, concreteTypes)
                from arg in this.ConvertToOpenImplementationArgumentMappings(subMapping, processedTypes).ToArray()
                select arg)
                .ToArray();
        }
Ejemplo n.º 20
0
        private void CheckForOverlappingRegistrations(Type serviceType)
        {
            var overlappingGroups = this.GetOverlappingGroupsFor(serviceType);

            if (overlappingGroups.Any())
            {
                if (!serviceType.Info().ContainsGenericParameters &&
                    overlappingGroups.Any(group => group.ServiceType == serviceType))
                {
                    throw new InvalidOperationException(
                        StringResources.CollectionTypeAlreadyRegistered(serviceType));
                }

                throw new InvalidOperationException(
                    StringResources.MixingCallsToRegisterCollectionIsNotSupported(serviceType));
            }
        }
Ejemplo n.º 21
0
        private object BuildProducerGroup(Type groupType, 
            InstanceProducer[] producersForGroup, int level)
        {
            if (producersForGroup.Length == 1)
            {
                var producer = producersForGroup[0];

                // This flattens the hierarchy when there is just one item in the group.
                return new DebuggerViewItem(
                    name: Helpers.ToFriendlyName(producer.ServiceType),
                    description: producer.DebuggerDisplay,
                    value: producersForGroup[0]);
            }

            if (groupType.Info().ContainsGenericParameters)
            {
                return this.BuildGenericGroup(groupType, producersForGroup, level);
            }
            else
            {
                return BuildNonGenericGroup(groupType, producersForGroup);
            }
        }
Ejemplo n.º 22
0
 private IEnumerable<RegistrationGroup> GetOverlappingGroupsFor(Type serviceType) => 
     from registrationGroup in this.RegistrationGroups
     where !registrationGroup.Appended
     where registrationGroup.ServiceType == serviceType
         || serviceType.Info().ContainsGenericParameters
         || registrationGroup.ServiceType.Info().ContainsGenericParameters
     select registrationGroup;