Пример #1
0
        /// <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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        /// <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());
        }
Пример #4
0
        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;
        }