/// <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); }); } }
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); }); } }
/// <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()); } } } }