Exemplo n.º 1
0
        private ServiceCallSite[] CreateArgumentCallSites(
            Type implementationType,
            CallSiteChain callSiteChain,
            ParameterInfo[] parameters,
            bool throwIfCallSiteNotFound)
        {
            var parameterCallSites = new ServiceCallSite[parameters.Length];

            for (int index = 0; index < parameters.Length; index++)
            {
                Type            parameterType = parameters[index].ParameterType;
                ServiceCallSite callSite      = GetCallSite(parameterType, callSiteChain);

                if (callSite == null && ParameterDefaultValue.TryGetDefaultValue(parameters[index], out object defaultValue))
                {
                    callSite = new ConstantCallSite(parameterType, defaultValue);
                }

                if (callSite == null)
                {
                    if (throwIfCallSiteNotFound)
                    {
                        throw new InvalidOperationException(SR.Format(SR.CannotResolveService,
                                                                      parameterType,
                                                                      implementationType));
                    }

                    return(null);
                }

                parameterCallSites[index] = callSite;
            }

            return(parameterCallSites);
        }
Exemplo n.º 2
0
        private static object[] PrepareArguments(
            IDictionary <string, object> argumentsInDictionary,
            HandlerMethodDescriptor handler)
        {
            if (handler.Parameters.Count == 0)
            {
                return(null);
            }

            var arguments = new object[handler.Parameters.Count];

            for (var i = 0; i < arguments.Length; i++)
            {
                var parameter = handler.Parameters[i];

                if (argumentsInDictionary.TryGetValue(parameter.ParameterInfo.Name, out var value))
                {
                    // Do nothing, already set the value.
                }
                else if (!ParameterDefaultValue.TryGetDefaultValue(parameter.ParameterInfo, out value) &&
                         parameter.ParameterInfo.ParameterType.IsValueType)
                {
                    value = Activator.CreateInstance(parameter.ParameterInfo.ParameterType);
                }

                arguments[i] = value;
            }

            return(arguments);
        }
Exemplo n.º 3
0
        private static object?BindParameter(ParameterInfo parameter, Type type, IConfiguration config,
                                            BinderOptions options)
        {
            string?parameterName = parameter.Name;

            if (parameterName is null)
            {
                throw new InvalidOperationException(SR.Format(SR.Error_ParameterBeingBoundToIsUnnamed, type));
            }

            var propertyBindingPoint = new BindingPoint(initialValue: config.GetSection(parameterName).Value, isReadOnly: false);

            if (propertyBindingPoint.Value is null)
            {
                if (ParameterDefaultValue.TryGetDefaultValue(parameter, out object?defaultValue))
                {
                    propertyBindingPoint.SetValue(defaultValue);
                }
                else
                {
                    throw new InvalidOperationException(SR.Format(SR.Error_ParameterHasNoMatchingConfig, type, parameterName));
                }
            }

            BindInstance(
                parameter.ParameterType,
                propertyBindingPoint,
                config.GetSection(parameterName),
                options);

            return(propertyBindingPoint.Value);
        }
Exemplo n.º 4
0
        private IServiceCallSite[] CreateArgumentCallSites(
            Type serviceType,
            Type implementationType,
            CallSiteChain callSiteChain,
            ParameterInfo[] parameters,
            bool throwIfCallSiteNotFound)
        {
            var parameterCallSites = new IServiceCallSite[parameters.Length];

            for (var index = 0; index < parameters.Length; index++)
            {
                var callSite = CreateCallSite(parameters[index].ParameterType, callSiteChain);

                if (callSite == null && ParameterDefaultValue.TryGetDefaultValue(parameters[index], out var defaultValue))
                {
                    callSite = new ConstantCallSite(serviceType, defaultValue);
                }

                if (callSite == null)
                {
                    if (throwIfCallSiteNotFound)
                    {
                        throw new InvalidOperationException(Resources.FormatCannotResolveService(
                                                                parameters[index].ParameterType,
                                                                implementationType));
                    }

                    return(null);
                }

                parameterCallSites[index] = callSite;
            }

            return(parameterCallSites);
        }
Exemplo n.º 5
0
 public object?[] GetConstructorArguments(IServiceProvider provider)
 {
     for (var index = 0; index != _parameters.Length; index++)
     {
         if (_parameterValues[index] == null)
         {
             var value = provider.GetService(_parameters[index].ParameterType);
             if (value == null)
             {
                 if (!ParameterDefaultValue.TryGetDefaultValue(_parameters[index], out var defaultValue))
                 {
                     throw new InvalidOperationException($"Unable to resolve service for type '{_parameters[index].ParameterType}' while attempting to activate '{_constructor.DeclaringType}'.");
                 }
                 else
                 {
                     _parameterValues[index] = defaultValue;
                 }
             }
             else
             {
                 _parameterValues[index] = value;
             }
         }
     }
     return(_parameterValues);
 }
Exemplo n.º 6
0
        private static object GetParameterDefaultValue(ParameterInfo parameterInfo)
        {
            if (!ParameterDefaultValue.TryGetDefaultValue(parameterInfo, out var defaultValue))
            {
                var defaultValueAttribute = parameterInfo.GetCustomAttribute <DefaultValueAttribute>(inherit: false);
                defaultValue = defaultValueAttribute?.Value;

                if (defaultValue == null && parameterInfo.ParameterType.IsValueType)
                {
                    defaultValue = Activator.CreateInstance(parameterInfo.ParameterType);
                }
            }
            return(defaultValue);
        }
Exemplo n.º 7
0
        public static bool TryGetDeclaredParameterDefaultValue(ParameterInfo parameterInfo, out object?defaultValue)
        {
            if (ParameterDefaultValue.TryGetDefaultValue(parameterInfo, out defaultValue))
            {
                return(true);
            }

            var defaultValueAttribute = parameterInfo.GetCustomAttribute <DefaultValueAttribute>(inherit: false);

            if (defaultValueAttribute != null)
            {
                defaultValue = defaultValueAttribute.Value;
                return(true);
            }

            return(false);
        }
Exemplo n.º 8
0
        private static Expression BuildFactoryExpression(
            ConstructorInfo constructor,
            int?[] parameterMap,
            Expression serviceProvider,
            Expression factoryArgumentArray)
        {
            var constructorParameters = constructor.GetParameters();
            var constructorArguments  = new Expression[constructorParameters.Length];

            for (var i = 0; i < constructorParameters.Length; i++)
            {
                var constructorParameter = constructorParameters[i];
                var parameterType        = constructorParameter.ParameterType;
                var hasDefaultValue      = ParameterDefaultValue.TryGetDefaultValue(constructorParameter, out var defaultValue);

                if (parameterMap[i] != null)
                {
                    constructorArguments[i] = Expression.ArrayAccess(factoryArgumentArray, Expression.Constant(parameterMap[i]));
                }
                else
                {
                    var parameterTypeExpression = new Expression[] { serviceProvider,
                                                                     Expression.Constant(parameterType, typeof(Type)),
                                                                     Expression.Constant(constructor.DeclaringType, typeof(Type)),
                                                                     Expression.Constant(hasDefaultValue) };
                    constructorArguments[i] = Expression.Call(GetServiceInfo, parameterTypeExpression);
                }

                // Support optional constructor arguments by passing in the default value
                // when the argument would otherwise be null.
                if (hasDefaultValue)
                {
                    var defaultValueExpression = Expression.Constant(defaultValue);
                    constructorArguments[i] = Expression.Coalesce(constructorArguments[i], defaultValueExpression);
                }

                constructorArguments[i] = Expression.Convert(constructorArguments[i], parameterType);
            }

            return(Expression.New(constructor, constructorArguments));
        }
        private ServiceCallSite[] CreateArgumentCallSites(
            Type serviceType,
            Type implementationType,
            CallSiteChain callSiteChain,
            ParameterInfo[] parameters,
            bool throwIfCallSiteNotFound)
        {
            var parameterCallSites = new ServiceCallSite[parameters.Length];

            for (var index = 0; index < parameters.Length; index++)
            {
                // 依次递归调用获取指定参数的ServiceCallSite
                var callSite = GetCallSite(parameters[index].ParameterType, callSiteChain);

                if (callSite == null &&
                    ParameterDefaultValue.TryGetDefaultValue(parameters[index], out var defaultValue))
                {
                    // 如果获取参数的ServiceCallSite失败但是该参数具有默认值
                    // 则直接以默认值来创建ConstantCallSite对象
                    callSite = new ConstantCallSite(serviceType, defaultValue);
                }

                // 如果当前callSite还为空,则代表出现无法实例化的参数类型
                // 如果允许抛出异常则抛出异常,如果不允许抛出异常则返回null
                if (callSite == null)
                {
                    if (throwIfCallSiteNotFound)
                    {
                        throw new InvalidOperationException(Resources.FormatCannotResolveService(
                                                                parameters[index].ParameterType,
                                                                implementationType));
                    }

                    return(null);
                }

                parameterCallSites[index] = callSite;
            }

            return(parameterCallSites);
        }
Exemplo n.º 10
0
        public object CreateInstance(IServiceProvider provider)
        {
            for (var index = 0; index < _parameters.Length; index++)
            {
                var parameter = _parameters[index];

                if (_parameterValues[index] is null)
                {
                    var value = provider.GetService(parameter.ParameterType);
                    if (value is null)
                    {
                        if (!ParameterDefaultValue.TryGetDefaultValue(parameter, out var defaultValue))
                        {
                            throw new InvalidOperationException($"Unable to resolve service for type '{_parameters[index].ParameterType}' while attempting to activate '{_constructor.DeclaringType}'.");
                        }

                        value = defaultValue;
                    }

                    _parameterValues[index] = value;
                }
            }

#if NETCOREAPP
            return(_constructor.Invoke(BindingFlags.DoNotWrapExceptions, binder: null, parameters: _parameterValues, culture: null));
#else
            try
            {
                return(_constructor.Invoke(_parameterValues));
            }
            catch (TargetInvocationException ex) when(ex.InnerException != null)
            {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                // The above line will always throw, but the compiler requires we throw explicitly.
                throw;
            }
#endif
        }
Exemplo n.º 11
0
        public object CreateInstance(IServiceProvider provider)
        {
            for (var index = 0; index != _parameters.Length; index++)
            {
                if (_parameterValues[index] == null)
                {
                    var value = provider.GetService(_parameters[index].ParameterType);
                    if (value == null)
                    {
                        if (!ParameterDefaultValue.TryGetDefaultValue(_parameters[index], out var defaultValue))
                        {
                            throw new InvalidOperationException($"Unable to resolve service for type '{_parameters[index].ParameterType}' while attempting to activate '{_constructor.DeclaringType}'.");
                        }
                        else
                        {
                            _parameterValues[index] = defaultValue;
                        }
                    }
                    else
                    {
                        _parameterValues[index] = value;
                    }
                }
            }

            try
            {
                return(_constructor.Invoke(_parameterValues));
            }
            catch (TargetInvocationException ex) when(ex.InnerException != null)
            {
                ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
                // The above line will always throw, but the compiler requires we throw explicitly.
                throw;
            }
        }