/// <summary> /// Creates an instance of dependency. /// </summary> /// <param name="implementationType">The autowiring implementation type.</param> /// <param name="autowiringStrategy">The autowiring strategy.</param> /// <param name="initializeInstanceLambdaStatements">The statements to initialize an instance.</param> public AutowiringDependency( [NotNull] Type implementationType, [CanBeNull] IAutowiringStrategy autowiringStrategy = null, [NotNull][ItemNotNull] params LambdaExpression[] initializeInstanceLambdaStatements) { _implementationType = implementationType ?? throw new ArgumentNullException(nameof(implementationType)); _autowiringStrategy = autowiringStrategy; _initializeInstanceExpressions = initializeInstanceLambdaStatements ?? throw new ArgumentNullException(nameof(initializeInstanceLambdaStatements)); _typeDescriptor = implementationType.Descriptor(); if (_typeDescriptor.IsInterface()) { throw new ArgumentException($"Type \"{implementationType}\" should not be an interface.", nameof(implementationType)); } if (_typeDescriptor.IsAbstract()) { throw new ArgumentException($"Type \"{implementationType}\" should not be an abstract class.", nameof(implementationType)); } if (!_typeDescriptor.IsGenericTypeDefinition()) { return; } _genericTypeParameters = _typeDescriptor.GetGenericTypeParameters(); if (_genericTypeParameters.Length > GenericTypeArguments.Arguments.Length) { throw new ArgumentException($"Too many generic type parameters in the type \"{implementationType}\".", nameof(implementationType)); } _genericParamsWithConstraints = new List <GenericParamsWithConstraints>(_genericTypeParameters.Length); var genericTypePos = 0; for (var position = 0; position < _genericTypeParameters.Length; position++) { var genericType = _genericTypeParameters[position]; if (!genericType.IsGenericParameter) { continue; } var descriptor = genericType.Descriptor(); if (descriptor.GetGenericParameterAttributes() == GenericParameterAttributes.None && !descriptor.GetGenericParameterConstraints().Any()) { if (!_typesMap.TryGetValue(genericType, out var curType)) { try { curType = GenericTypeArguments.Arguments[genericTypePos++]; _typesMap[genericType] = curType; } catch (IndexOutOfRangeException ex) { throw new BuildExpressionException("Too many generic arguments.", ex); } } _genericTypeParameters[position] = curType; } else { _genericParamsWithConstraints.Add(new GenericParamsWithConstraints(descriptor, position)); } } if (_genericParamsWithConstraints.Count == 0) { _implementationType = _typeDescriptor.MakeGenericType(_genericTypeParameters); } else { _hasGenericParamsWithConstraints = true; } }