Пример #1
0
        private static void RegisterConfiguration(ContainerBuilder builder, AutoConfigurationDetail autoConfigurationDetail)
        {
            //注册为工厂
            foreach (var beanMethod in autoConfigurationDetail.BeanMethodInfoList)
            {
                if (!beanMethod.Item2.IsVirtual)
                {
                    throw new InvalidOperationException(
                              $"The Configuration class `{autoConfigurationDetail.AutoConfigurationClassType.FullName}` method `{beanMethod.Item2.Name}` must be virtual!");
                }

                if (!ProxyUtil.IsAccessible(beanMethod.Item2.ReturnType))
                {
                    throw new InvalidOperationException(
                              $"The Configuration class `{autoConfigurationDetail.AutoConfigurationClassType.FullName}` method `{beanMethod.Item2.Name}` returnType is not accessible!");
                }

                if (beanMethod.Item2.ReturnType.IsValueType || beanMethod.Item2.ReturnType.IsEnum)
                {
                    throw new InvalidOperationException(
                              $"The Configuration class `{autoConfigurationDetail.AutoConfigurationClassType.FullName}` method `{beanMethod.Item2.Name}` returnType is invalid!");
                }

                //包装这个方法成功工厂
                //先拿到AutoConfiguration class的实例
                //注册一个方法到容器 拿到并传入IComponentContext

                builder.RegisterCallback(cr =>
                {
                    var instanceType = beanMethod.Item3;//返回类型

                    var rb = RegistrationBuilder.ForDelegate(instanceType, ((context, parameters) =>
                    {
                        var autoConfigurationInstance = context.Resolve(autoConfigurationDetail.AutoConfigurationClassType);
                        var instance = AutoConfigurationHelper.InvokeInstanceMethod(context, autoConfigurationDetail, autoConfigurationInstance, beanMethod.Item2);
                        if (typeof(Task).IsAssignableFrom(instance.GetType()))
                        {
                            return(typeof(Task <>).MakeGenericType(instanceType).GetProperty("Result").GetValue(instance));
                        }
                        return(instance);
                    }));

                    if (!string.IsNullOrEmpty(beanMethod.Item1.Key))
                    {
                        rb.Keyed(beanMethod.Item1.Key, instanceType).Named("`1System.Collections.Generic.IEnumerable`1" + instanceType.FullName, instanceType);
                    }
                    else
                    {
                        rb.As(instanceType).Named("`1System.Collections.Generic.IEnumerable`1" + instanceType.FullName, instanceType);
                    }

                    rb.SingleInstance();
                    RegistrationBuilder.RegisterSingleComponent(cr, rb);
                });
            }
        }
Пример #2
0
        private void DoAutofacConfiguration(ContainerBuilder builder)
        {
            AutoConfigurationList list = new AutoConfigurationList
            {
                AutoConfigurationDetailList = new List <AutoConfigurationDetail>()
            };

            try
            {
                var allConfiguration = GetAllAutofacConfiguration();
                if (!allConfiguration.Any())
                {
                    return;
                }
                if (!string.IsNullOrEmpty(this.AutofacConfigurationKey))
                {
                    allConfiguration = allConfiguration.Where(r => r.Key.Equals(this.AutofacConfigurationKey)).ToList();
                }

                foreach (var configuration in allConfiguration)
                {
                    var beanTypeMethodList = configuration.Type.GetAllInstanceMethod(false);
                    var bean = new AutoConfigurationDetail
                    {
                        AutoConfigurationClassType = configuration.Type,
                        BeanMethodInfoList         = new List <Tuple <Bean, MethodInfo> >(),
                        MetaSourceDataList         = new List <MetaSourceData>()
                    };
                    foreach (var beanTypeMethod in beanTypeMethodList)
                    {
                        var beanAttribute = beanTypeMethod.GetCustomAttribute <Bean>();
                        if (beanAttribute == null)
                        {
                            continue;
                        }
                        bean.BeanMethodInfoList.Add(new Tuple <Bean, MethodInfo>(beanAttribute, beanTypeMethod));
                    }

                    builder.RegisterType(configuration.Type).AsSelf().SingleInstance();//注册为单例模式
                    list.AutoConfigurationDetailList.Add(bean);

                    EnumerateMetaSourceAttributes(bean.AutoConfigurationClassType, bean.MetaSourceDataList);
                }
            }
            finally
            {
                builder.RegisterInstance(list).SingleInstance();
            }
        }
Пример #3
0
        public static object InvokeInstanceMethod(IComponentContext context, AutoConfigurationDetail autoConfigurationDetail, object autoConfigurationInstance, MethodInfo methodInfo)
        {
            try
            {
                var parameters = methodInfo.GetParameters();
                if (parameters.Length == 0)
                {
                    return(methodInfo.Invoke(autoConfigurationInstance, null));
                }

                //自动类型注入

                List <object> parameterObj = new List <object>();
                foreach (var parameter in parameters)
                {
                    var autowired = parameter.GetCustomAttribute <Autowired>();
                    if (autowired != null)
                    {
                        parameterObj.Add(autowired.ResolveParameter(parameter, context));
                        continue;
                    }

                    var value = parameter.GetCustomAttribute <Value>();
                    if (value != null)
                    {
                        parameterObj.Add(value.ResolveParameterWithConfiguration(autoConfigurationDetail, parameter, context));
                        continue;
                    }

                    if (parameter.HasDefaultValue)
                    {
                        parameterObj.Add(parameter.RawDefaultValue);
                        continue;
                    }

                    if (parameter.IsOptional)
                    {
                        parameterObj.Add(Type.Missing);
                        continue;
                    }

                    if (parameter.IsOut)
                    {
                        parameterObj.Add(Type.Missing);
                        continue;
                    }

                    if (parameter.ParameterType.IsValueType || parameter.ParameterType.IsEnum)
                    {
                        parameterObj.Add(parameter.RawDefaultValue);
                        continue;
                    }


                    parameterObj.Add(context.Resolve(parameter.ParameterType));
                }

                return(methodInfo.Invoke(autoConfigurationInstance, parameterObj.ToArray()));
            }
            catch (Exception e)
            {
                throw new InvalidOperationException($"The Configuration class `{autoConfigurationDetail.AutoConfigurationClassType.FullName}` method `{methodInfo.Name}` invoke fail!", e);
            }
        }
Пример #4
0
        /// <summary>
        ///  创建Value的包装器
        /// </summary>
        /// <param name="value"></param>
        /// <param name="memberType"></param>
        /// <param name="classType"></param>
        /// <param name="parameterInfo"></param>
        /// <param name="autoConfigurationDetail"></param>
        /// <returns></returns>
        public object CreateValueFactory(Value value, Type memberType, Type classType, string parameterInfo, AutoConfigurationDetail autoConfigurationDetail)
        {
            var           targetType       = memberType.GenericTypeArguments[0];
            var           valueType        = typeof(ValueObjectFactory <>);
            var           valueFactoryType = valueType.MakeGenericType(targetType);
            Func <object> function         = () => value.Resolve(_context, classType, targetType, parameterInfo, autoConfigurationDetail);

            return(Activator.CreateInstance(valueFactoryType, new object[] { function }));
        }
Пример #5
0
 /// <summary>
 /// AutoConfiguration类的value注入
 /// </summary>
 /// <param name="detail"></param>
 /// <param name="parameter"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 internal object ResolveParameterWithConfiguration(AutoConfigurationDetail detail, ParameterInfo parameter, IComponentContext context)
 {
     return(Resolve(context, parameter.Member.DeclaringType, parameter.ParameterType, parameter.Name, detail));
 }
Пример #6
0
        private string ResolvePlaceholder(IComponentContext context, Type classType, string placeholder, AutoConfigurationDetail autoConfigurationDetail = null)
        {
            string propertyValue = null;

            if (this.EnvironmentVariableMode == EnvironmentVariableMode.Override)
            {
                propertyValue = Environment.GetEnvironmentVariable(placeholder);
            }

            if (propertyValue == null)
            {
                List <MetaSourceData> MetaSourceList = null;
                if (autoConfigurationDetail != null)
                {
                    MetaSourceList = autoConfigurationDetail.MetaSourceDataList;
                }
                else
                {
                    var componentModelCacheSingleton = context.Resolve <ComponentModelCacheSingleton>();
                    if (componentModelCacheSingleton.ComponentModelCache.TryGetValue(classType, out var component))
                    {
                        MetaSourceList = component.MetaSourceList;
                    }
                }

                if (MetaSourceList != null)
                {
                    foreach (var metaSource in MetaSourceList)
                    {
                        if (metaSource.Configuration == null)
                        {
                            continue;
                        }

                        IConfigurationSection metData = metaSource.Configuration.GetSection(placeholder);
                        var parameterValue            = metData?.Value;
                        if (parameterValue == null)
                        {
                            //表示key不存在 从下一个source里面去寻找
                            continue;
                        }

                        propertyValue = parameterValue;
                        break;
                    }
                }
            }

            if (propertyValue == null && EnvironmentVariableMode == EnvironmentVariableMode.Fallback)
            {
                propertyValue = Environment.GetEnvironmentVariable(placeholder);
            }

            return(propertyValue);
        }
Пример #7
0
        private object ResolveEmbeddedValue(IComponentContext context, Type classType, string strVal, AutoConfigurationDetail autoConfigurationDetail = null)
        {
            int startIndex = strVal.IndexOf(DefaultPlaceholderPrefix, StringComparison.Ordinal);

            while (startIndex != -1)
            {
                int endIndex = strVal.IndexOf(DefaultPlaceholderSuffix, startIndex + DefaultPlaceholderPrefix.Length, StringComparison.Ordinal);
                if (endIndex != -1)
                {
                    int    pos           = startIndex + DefaultPlaceholderPrefix.Length;
                    string placeholder   = strVal.Substring(pos, endIndex - pos);
                    string resolvedValue = ResolvePlaceholder(context, classType, placeholder, autoConfigurationDetail);
                    if (resolvedValue != null)
                    {
                        strVal     = strVal.Substring(0, startIndex) + resolvedValue + strVal.Substring(endIndex + 1);
                        startIndex = strVal.IndexOf(DefaultPlaceholderPrefix, startIndex + resolvedValue.Length, StringComparison.Ordinal);
                    }
                    else if (IgnoreUnresolvablePlaceholders)
                    {
                        return(strVal);
                    }
                    else
                    {
                        throw new Exception(string.Format("Could not resolve placeholder '{0}'.", placeholder));
                    }
                }
                else
                {
                    startIndex = -1;
                }
            }

            return(strVal);
        }
Пример #8
0
        /// <summary>
        /// 对于memberInfo 或者  parameterInfo 进行设值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="classType"></param>
        /// <param name="memberType"></param>
        /// <param name="parameterInfo"></param>
        /// <param name="autoConfigurationDetail"></param>
        /// <returns></returns>
        internal object Resolve(IComponentContext context, Type classType, Type memberType, string parameterInfo = null, AutoConfigurationDetail autoConfigurationDetail = null)
        {
            if (classType == null)
            {
                return(null);
            }
            if (string.IsNullOrEmpty(this.value))
            {
                return(null);
            }
            try
            {
                //判断类型是否是IValue
                if ((typeof(IObjectFactory).IsAssignableFrom(memberType)))
                {
                    return(context.Resolve <ObjectBeanFactory>().CreateValueFactory(this, memberType, classType, parameterInfo, autoConfigurationDetail));
                }

                //先把 ${} 的 placehoder 全部替换掉
                var parameterValue = ResolveEmbeddedValue(context, classType, this.value, autoConfigurationDetail);
                int startIndex     = parameterValue.ToString().IndexOf("#{", StringComparison.Ordinal);
                if (startIndex != -1)
                {
                    int endIndex = parameterValue.ToString().LastIndexOf(DefaultPlaceholderSuffix, StringComparison.Ordinal);
                    if (endIndex != -1)
                    {
                        Dictionary <string, object> vars = new Dictionary <string, object>
                        {
                            ["_sprint_context_resove_"] = new SprintContextResove((type, name) =>
                            {
                                if (type != null && !string.IsNullOrEmpty(name))
                                {
                                    return(context.ResolveKeyed(name, type));
                                }
                                if (type != null)
                                {
                                    return(context.Resolve(type));
                                }
                                if (!string.IsNullOrEmpty(name))
                                {
                                    //从当前的Assembly去loadType
                                    var arr = name.Split('>');
                                    if (arr.Length == 2)
                                    {
                                        var resolveType = classType.Assembly.GetType(classType.Namespace + "." + arr[0]);
                                        return(resolveType == null ? null : context.ResolveKeyed(arr[1], resolveType));
                                    }
                                    else
                                    {
                                        var resolveType = classType.Assembly.GetType(classType.Namespace + "." + name);
                                        return(resolveType == null ? null : context.Resolve(resolveType));
                                    }
                                }

                                return(null);
                            })
                        };
                        //El表达式

                        int    pos        = startIndex + DefaultPlaceholderPrefix.Length;
                        string expression = parameterValue.ToString().Substring(pos, endIndex - pos);
                        parameterValue = ExpressionEvaluator.GetValue(null, expression, vars);
                    }
                }

                if (parameterValue == null)
                {
                    return(null);
                }

                return(TypeConversionUtils.ConvertValueIfNecessary(memberType, parameterValue, null));
            }
            catch (Exception ex)
            {
                throw new DependencyResolutionException($"Value set error,can not resolve class type:{classType.FullName} =====>" +
                                                        $" {parameterInfo ?? memberType.Name} "
                                                        + (!string.IsNullOrEmpty(this.value) ? $",with value:[{this.value}]" : ""), ex);
            }
        }
Пример #9
0
        /// <summary>
        /// 对于memberInfo 或者  parameterInfo 进行设值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="classType"></param>
        /// <param name="memberType"></param>
        /// <param name="memberInfo"></param>
        /// <param name="parameterInfo"></param>
        /// <param name="autoConfigurationDetail"></param>
        /// <returns></returns>
        private object Resolve(IComponentContext context, Type classType, Type memberType, MemberInfo memberInfo, ParameterInfo parameterInfo = null, AutoConfigurationDetail autoConfigurationDetail = null)
        {
            if (classType == null)
            {
                return(null);
            }
            if (string.IsNullOrEmpty(this.value))
            {
                return(null);
            }
            try
            {
                //先把 ${} 的 placehoder 全部替换掉
                var parameterValue = ResolveEmbeddedValue(context, classType, this.value, autoConfigurationDetail);
                int startIndex     = parameterValue.ToString().IndexOf("#{", StringComparison.Ordinal);
                if (startIndex != -1)
                {
                    int endIndex = parameterValue.ToString().LastIndexOf(DefaultPlaceholderSuffix, StringComparison.Ordinal);
                    if (endIndex != -1)
                    {
                        Dictionary <string, object> vars = new Dictionary <string, object>
                        {
                            ["_sprint_context_resove_"] = new SprintContextResove((type, name) =>
                            {
                                if (!string.IsNullOrEmpty(name))
                                {
                                    return(context.ResolveKeyed(name, type));
                                }
                                return(context.Resolve(type));
                            })
                        };
                        //El表达式

                        int    pos        = startIndex + DefaultPlaceholderPrefix.Length;
                        string expression = parameterValue.ToString().Substring(pos, endIndex - pos);
                        parameterValue = ExpressionEvaluator.GetValue(null, expression, vars);
                    }
                }

                if (parameterValue == null)
                {
                    return(null);
                }

                return(TypeConversionUtils.ConvertValueIfNecessary(memberType, parameterValue, null));

                //var parseValue = parameterInfo == null
                //    ? TypeManipulation.ChangeToCompatibleType(parameterValue, memberType, memberInfo)
                //    : TypeManipulation.ChangeToCompatibleType(parameterValue, memberType, parameterInfo);
                //return parseValue;
            }
            catch (Exception ex)
            {
                throw new DependencyResolutionException($"Value set error,can not resolve class type:{classType.FullName} =====>" +
                                                        $" {(parameterInfo == null ? memberType.Name : parameterInfo.Name)} "
                                                        + (!string.IsNullOrEmpty(this.value) ? $",with value:[{this.value}]" : ""), ex);
            }
        }