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