Exemplo n.º 1
0
        /// <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;
            }
        }