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