Example #1
0
        /// <summary>
        /// init方法和Release方法
        /// </summary>
        /// <typeparam name="TReflectionActivatorData"></typeparam>
        /// <typeparam name="TSingleRegistrationStyle"></typeparam>
        /// <param name="component"></param>
        /// <param name="registrar"></param>
        protected virtual void RegisterMethods <TReflectionActivatorData, TSingleRegistrationStyle>(ComponentModel component,
                                                                                                    IRegistrationBuilder <object, TReflectionActivatorData, TSingleRegistrationStyle> registrar)
            where TReflectionActivatorData : ReflectionActivatorData
            where TSingleRegistrationStyle : SingleRegistrationStyle
        {
            MethodInfo AssertMethod(Type type, string methodName)
            {
                var        emethodName = methodName.Contains(".") ? methodName.Split('.').LastOrDefault() : methodName;
                MethodInfo method      = null;

                try
                {
                    BindingFlags flags = BindingFlags.Public |
                                         BindingFlags.NonPublic |
                                         BindingFlags.Static |
                                         BindingFlags.Instance |
                                         BindingFlags.DeclaredOnly;
                    method = type.GetMethod(emethodName, flags);
                }
                catch (Exception)
                {
                    //如果有多个就抛出异常
                    throw new DependencyResolutionException($"find method: {methodName} in type:{type.FullName} have more then one");
                }

                if (method == null)
                {
                    throw new DependencyResolutionException($"find method: {methodName} in type:{type.FullName} error");
                }

                return(method);
            }

            if (component == null)
            {
                throw new ArgumentNullException(nameof(component));
            }

            if (registrar == null)
            {
                throw new ArgumentNullException(nameof(registrar));
            }

            if (!string.IsNullOrEmpty(component.InitMethod))
            {
                var method = AssertMethod(component.CurrentType, component.InitMethod);
                registrar.OnActivated(e => { AutoConfigurationHelper.InvokeInstanceMethod(e.Instance, method, e.Context); });
            }

            if (!string.IsNullOrEmpty(component.DestroyMethod))
            {
                var method = AssertMethod(component.CurrentType, component.DestroyMethod);
                if (method.GetParameters().Any())
                {
                    throw new DependencyResolutionException($"class `{component.CurrentType.FullName}` DestroyMethod `{component.DestroyMethod}` must be no parameters");
                }
                registrar.OnRelease(e => { method.Invoke(e, null); });
            }
        }
Example #2
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);
                });
            }
        }
Example #3
0
        /// <summary>
        /// 执行自动注册
        /// </summary>
        /// <param name="context"></param>
        public void Start(IComponentContext context)
        {
            lock (this)
            {
                context.TryResolve <AutoConfigurationList>(out var autoConfigurationList);
                if (autoConfigurationList == null || autoConfigurationList.AutoConfigurationDetailList == null || !autoConfigurationList.AutoConfigurationDetailList.Any())
                {
                    return;
                }
                foreach (var autoConfigurationDetail in autoConfigurationList.AutoConfigurationDetailList)
                {
                    context.TryResolve(autoConfigurationDetail.AutoConfigurationClassType, out var autoConfigurationInstance);
                    if (autoConfigurationInstance == null)
                    {
                        continue;
                    }


                    foreach (var beanMethod in autoConfigurationDetail.BeanMethodInfoList)
                    {
                        if (beanMethod.Item2.IsVirtual)
                        {
                            throw new InvalidOperationException(
                                      $"The Configuration class `{autoConfigurationDetail.AutoConfigurationClassType.FullName}` method `{beanMethod.Item2.Name}` can not be virtual!");
                        }

                        if (beanMethod.Item2.GetParameters().Length != 0)
                        {
                            throw new InvalidOperationException(
                                      $"The Configuration class `{autoConfigurationDetail.AutoConfigurationClassType.FullName}` method `{beanMethod.Item2.Name}` can only none parameters!");
                        }
                        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!");
                        }

                        var result = beanMethod.Item2.Invoke(autoConfigurationInstance, null);
                        if (result == null)
                        {
                            continue;
                        }
                        context.ComponentRegistry.Register(AutoConfigurationHelper.RegisterInstance(context.ComponentRegistry, beanMethod.Item2.ReturnType, result, beanMethod.Item1.Key).CreateRegistration());
                    }
                }
            }
        }