Exemple #1
0
        private void AddSingletonFactoryCreateMethod(Type valueType)
        {
            var singletonFieldBuilder = TypeBuilder.DefineField("_singleton", valueType, FieldAttributes.Private);
            var ilGenerator           = _methodBuilder.GetILGenerator();
            var label = ilGenerator.DefineLabel();

            ilGenerator.DeclareLocal(valueType);
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldfld, singletonFieldBuilder);
            ilGenerator.Emit(OpCodes.Brtrue_S, label);
            ilGenerator.Emit(OpCodes.Ldarg_0);
            foreach (var constructorParameterType in ConstructorFieldBuilders)
            {
                var constructorParameterBuilders = ContainerConstruction.GetOrAddFactoryBuilder(constructorParameterType.Key);
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldfld, constructorParameterType.Value);
                ilGenerator.Emit(OpCodes.Callvirt, constructorParameterBuilders.MethodBuilder);
                ilGenerator.Emit(OpCodes.Castclass, constructorParameterType.Key);
            }

            ilGenerator.Emit(OpCodes.Newobj, valueType.GetPublicConstructor());
            ilGenerator.Emit(OpCodes.Stfld, singletonFieldBuilder);
            ilGenerator.MarkLabel(label);
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldfld, singletonFieldBuilder);
            ilGenerator.Emit(OpCodes.Ret);

            var createMethod = typeof(IFactory).GetRuntimeMethod(nameof(IFactory.Get), new Type[0]);

            TypeBuilder.DefineMethodOverride(_methodBuilder, createMethod);
        }
Exemple #2
0
        public IFactory Create(Type keyType)
        {
            var factoryBuilder  = ContainerConstruction.GetOrAddFactoryBuilder(keyType);
            var constructorArgs = factoryBuilder.ValueType.GetPublicConstructor().GetConstructorParameterTypes().Select(Create).Cast <object>().ToArray();

            return((IFactory)Activator.CreateInstance(factoryBuilder.TypeBuilder.CreateTypeInfo().AsType(), constructorArgs.Length == 0 ? null : constructorArgs));
        }
        private void AddTransientFactoryCreateMethod(Type valueType)
        {
            var ilGenerator = _methodBuilder.GetILGenerator();

            foreach (var constructorParameterType in ConstructorFieldBuilders)
            {
                var constructorParameterBuilders = ContainerConstruction.GetOrAddFactoryBuilder(constructorParameterType.Key);
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldfld, constructorParameterType.Value);
                ilGenerator.Emit(OpCodes.Callvirt, constructorParameterBuilders.MethodBuilder);
                ilGenerator.Emit(OpCodes.Castclass, constructorParameterType.Key);
            }

            ilGenerator.Emit(OpCodes.Newobj, valueType.GetPublicConstructor());
            ilGenerator.Emit(OpCodes.Ret);
            var createMethod = typeof(IFactory).GetRuntimeMethod("Get", new Type[0]);

            _typeBuilder.DefineMethodOverride(_methodBuilder, createMethod);
        }
Exemple #4
0
        protected void AddConstructor(Type valueType, TypeBuilder typeBuilder)
        {
            var constructorParameterTypes = valueType.GetPublicConstructor().GetConstructorParameterTypes();

            if (constructorParameterTypes.Length == 0)
            {
                return;
            }

            var constructorTypes = constructorParameterTypes.Select(x => new { ConstructorType = x, FactoryType = ContainerConstruction.GetOrAddFactoryBuilder(x).TypeBuilder.AsType() }).ToArray();

            var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorTypes.Select(x => x.FactoryType).ToArray());
            var ilGenerator        = constructorBuilder.GetILGenerator();

            ilGenerator.DeclareLocal(valueType);
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Call, typeof(object).GetTypeInfo().DeclaredConstructors.First());
            var parameterCounter = 0;

            foreach (var constructorType in constructorTypes)
            {
                var fieldBuilder = typeBuilder.DefineField($"_field{++parameterCounter}", constructorType.FactoryType, FieldAttributes.Private);
                ilGenerator.Emit(OpCodes.Ldarg_0);
                ilGenerator.Emit(OpCodes.Ldarg_S, parameterCounter);
                ilGenerator.Emit(OpCodes.Stfld, fieldBuilder);
                ConstructorFieldBuilders.Add(constructorType.ConstructorType, fieldBuilder);
            }

            ilGenerator.Emit(OpCodes.Ret);
        }