/// <summary> /// 객체를 질의합니다. /// </summary> /// <param name="type">질의할 클래스타입</param> /// <returns>질의된 객체</returns> public virtual object GetManaged(Type type) { if (_managedInfos.TryGetValue(type, out var cachedManagedInfo)) { return(cachedManagedInfo.Object); } var managedAttribute = type.GetCustomAttribute <ManagedAttribute>(); CreateManagedException.Check(managedAttribute != null, CreateManagedError.NotManagedClass); var parameterInfos = GetInjectedParameters(type); var parameters = parameterInfos.Select(info => GetManaged(info.ParameterType)).ToArray(); ManagedInfo managedInfo; var managedType = managedAttribute.ManagedType; switch (managedType) { case ManagedType.Singleton: var managed = Create(type, parameters); managedInfo = new ManagedInfo(type, managedAttribute, () => managed); break; case ManagedType.Proto: managedInfo = new ManagedInfo(type, managedAttribute, () => Create(type, parameters)); break; default: throw new CreateManagedException(CreateManagedError.UnsupportedManagedType); } _managedInfos[type] = managedInfo; return(managedInfo.Object); }
private Ganerator GetCachedGeneratorInternal(Type type, object[] parameters) { if (_generators.ContainsKey(type)) { return(_generators[type]); } // 사용될 생성자를 찾기 위해 인자값들을 이용하여 타입을 가져옴. var parameterTypes = parameters?.Select(param => param.GetType()).ToArray() ?? Type.EmptyTypes; var constructor = type.GetConstructor(parameterTypes); CreateManagedException.Check(constructor != null, CreateManagedError.NotExistMatchedConstructor); var parameterInfos = constructor.GetParameters(); var dm = new DynamicMethod($"{type.Name}Factory+{Guid.NewGuid()}", typeof(object), new[] { typeof(object[]) }); var il = dm.GetILGenerator(); for (int i = 0; i < parameterInfos.Length; i++) { il.Emit(Ldarg_0); // [params] il.Emit(Ldc_I4, i); // [params] [index] il.Emit(Ldelem_Ref); // [params[index]] var parameterType = parameterInfos[i].ParameterType; if (parameterType.IsValueType) { il.Emit(Unbox_Any, parameterType); } } il.Emit(Newobj, constructor); il.Emit(Ret); return(_generators[type] = dm.CreateDelegate(typeof(Ganerator)) as Ganerator); }
/// <summary> /// 객체를 질의합니다. /// </summary> /// <param name="type">질의할 클래스타입</param> /// <returns>질의된 객체</returns> public virtual object GetManaged(Type type) { if (type == null) { throw new ArgumentNullException(nameof(type)); } // 아직 등록되지 않은 Assembly면 등록 if (!_registeredAssemblies.Contains(type.Assembly)) { Register(type.Assembly); } // 이미 만들어둔 getter가 있으면 새로 만들지 않음. if (_managedGetters.TryGetValue(type, out var cachedManagedGetter)) { return(cachedManagedGetter()); } var definition = _definitions.FirstOrDefault(info => info.TargetType == type); CreateManagedException.Check(definition != null, CreateManagedError.NotManagedClass); var parameters = definition.NeedParameterTypes.Select(GetManaged).ToArray(); Func <object> managedGetter = CreateGetter(definition, parameters); _managedGetters[type] = managedGetter; return(managedGetter()); }
public ConfigurationManagedDefinition(MethodInfo methodInfo) : base(methodInfo.ReturnType) { if (methodInfo == null) { throw new ArgumentNullException(nameof(methodInfo)); } var managedAttribute = methodInfo.GetCustomAttribute <ManagedAttribute>(); CreateManagedException.Check(managedAttribute != null, CreateManagedError.NotManagedClass); ManagedType = managedAttribute.ManagedType; var configurationType = methodInfo.DeclaringType; // FactoryMethod 등록시에는 NeedParameterTypes의 첫번째에 해당 메소드의 DeclaringType이 들어간다. var parameterTypes = methodInfo.GetParameterTypes(); NeedParameterTypes = new Type[1 + parameterTypes.Length]; NeedParameterTypes[0] = configurationType; for (int i = 0; i < parameterTypes.Length; i++) { NeedParameterTypes[i + 1] = parameterTypes[i]; } var dynamicMethod = new DynamicMethod(GeneratorName, typeof(object), new[] { typeof(object[]) }); var il = dynamicMethod.GetILGenerator(); il.Emit(Ldarg_0); il.Emit(Ldc_I4_0); il.Emit(Ldelem_Ref); il.Emit(Castclass, configurationType); for (int i = 0; i < parameterTypes.Length; i++) { il.Emit(Ldarg_0); il.Emit(Ldc_I4, i + 1); il.Emit(Ldelem_Ref); var parameterType = parameterTypes[i]; if (parameterType.IsValueType) { il.Emit(Unbox_Any, parameterType); } else { il.Emit(Castclass, parameterType); } } il.Emit(Call, methodInfo); il.Emit(Ret); ManagedGenerator = dynamicMethod.CreateDelegate(typeof(Generator)) as Generator; }
public ConstructorManagedDefinition(ConstructorInfo constructorInfo) : base(constructorInfo.DeclaringType) { if (constructorInfo == null) { throw new ArgumentNullException(nameof(constructorInfo)); } var managedAttribute = TargetType.GetCustomAttribute <ManagedAttribute>(); CreateManagedException.Check(managedAttribute != null, CreateManagedError.NotManagedClass); ManagedType = managedAttribute.ManagedType; NeedParameterTypes = constructorInfo.GetParameterTypes(); var dynamicMethod = new DynamicMethod(GeneratorName, typeof(object), new[] { typeof(object[]) }, TargetType); var il = dynamicMethod.GetILGenerator(); for (int i = 0; i < NeedParameterTypes.Length; i++) { il.Emit(Ldarg_0); il.Emit(Ldc_I4, i); il.Emit(Ldelem_Ref); var parameterType = NeedParameterTypes[i]; if (parameterType.IsValueType) { il.Emit(Unbox_Any, parameterType); } else { il.Emit(Castclass, parameterType); } } il.Emit(Newobj, constructorInfo); il.Emit(Ret); ManagedGenerator = dynamicMethod.CreateDelegate(typeof(Generator)) as Generator; }