/// <summary>
        /// Gets a registration for some contract type.
        /// </summary>
        /// <param name="contractType">The contract type.</param>
        /// <param name="container">The container.</param>
        /// <returns><value>The registration item</value> if this source can handle it, otherwise <value>null</value>.</returns>
        public RegistrationItem GetRegistrationFor(Type contractType, IContainer container)
        {
            Type[] genericArguments = contractType.GetGenericArguments();

            // Try get the Registration for the open generic type.
            RegistrationItem openGenericTypeRegistration = null;

            _registrationContainer.TryGetRegistration(contractType.GetGenericTypeDefinition(), out openGenericTypeRegistration);

            if (openGenericTypeRegistration == null)
            {
                throw new RegistrationNotFoundException(string.Format(Resources.RegistrationNotFoundFormat,
                                                                      contractType.GetGenericTypeDefinition()),
                                                        contractType.GetGenericTypeDefinition());
            }

            // Try to find a closed generic which passes the open signature.
            var registrationItem = _registrationContainer
                                   .GetRegistration(registration => contractType.IsAssignableFrom(registration.ImplementationType));

            Type implementationType = null;

            if (registrationItem != null)
            {
                implementationType = registrationItem.ImplementationType;
            }

            // RegisterInstance closed generic type on-the-fly, if no match until now.
            if (implementationType == null)
            {
                implementationType = openGenericTypeRegistration.ImplementationType.MakeGenericType(genericArguments);
            }

            var closedGenericRegistration = new RegistrationItem(contractType)
            {
                Activator = new ReflectionActivator(
                    implementationType,
                    container.Resolve <IConstructorSelector>(),
                    container.Resolve <IArgumentCollector>()
                    ),
                ImplementationType = implementationType
            };

            var fluentRegistration = new FluentRegistration(closedGenericRegistration);

            fluentRegistration.ControlledBy(openGenericTypeRegistration.Lifecycle.GetType());

            return(closedGenericRegistration);
        }
예제 #2
0
        /// <summary>
        ///     Resolves a contract (include subcontracts).
        /// </summary>
        /// <param name="contractType">The contract type.</param>
        /// <param name="arguments">The arguments.</param>
        /// <param name="namedArguments">The named arguments.</param>
        /// <returns>The resolved instance as object.</returns>
        private object ResolveInternal(Type contractType, IEnumerable <object> arguments,
                                       IDictionary <string, object> namedArguments)
        {
            RegistrationItem registrationItem;

            if (!_registrationContainer.TryGetRegistration(contractType, out registrationItem))
            {
                if (_registrationContainer.HasDuplicateRegistration(contractType))
                {
                    throw new RegistrationNotFoundException(
                              Resources.RegistrationNotFoundBecauseDuplicate.FormatWith(contractType), contractType);
                }

                // No registration found yet, try to create one with available registration sources.
                IRegistrationSource registrationSourceToUse = null;

                for (int i = 0; i < _registrationContainer.RegistrationSources.Count; i++)
                {
                    var currentRegistrationSource = _registrationContainer.RegistrationSources[i];

                    if (currentRegistrationSource.SourceSupportsTypeSelector(contractType))
                    {
                        registrationSourceToUse = currentRegistrationSource;
                        break;
                    }
                }

                if (registrationSourceToUse == null)
                {
                    throw new RegistrationNotFoundException(
                              Resources.RegistrationNotFoundFormat.FormatWith(contractType), contractType);
                }

                registrationItem = registrationSourceToUse.GetRegistrationFor(contractType, this);

                _registrationContainer.AddRegistration(registrationItem);
            }

            // Add runtime arguments to registration.
            AddArgumentsToRegistration(registrationItem, arguments, namedArguments);

            // Activate existing registration.
            var result = this.Resolve(registrationItem);

            return(result);
        }