Esempio n. 1
1
 public FactoryClass(IConstructorArgList argList, IList<IFactoryMethod> methods)
 {
     m_argList = argList;
     Methods = methods;
     foreach (var definition in methods.SelectMany(m => m.ConstructorArgs))
         argList.Add(definition);
 }
Esempio n. 2
0
        public void EmitMethod(TypeBuilder tb, IConstructorArgList constructorArgList)
        {
            var methodAttributes = MethodAttributes.Public |
                                   MethodAttributes.HideBySig |
                                   MethodAttributes.NewSlot |
                                   MethodAttributes.Virtual |
                                   MethodAttributes.Final;
            var method = tb.DefineMethod(
                Name,
                methodAttributes,
                CallingConventions.Standard,
                ReturnType,
                ConstructorArgs.OfType<IPassedConstructorArgDefinition>().Select(a => a.ParameterType).ToArray());

            var consArgTypes = ConstructorArgs.Select(a => a.ParameterType).ToArray();

            var conObj = ReturnImplType.GetConstructor(consArgTypes);

            if (conObj == null)
                throw new Exception("Failed to find constructor of type " + ReturnImplType.FullName + " with arguments: " + string.Join(", ", consArgTypes.Select(a => a.FullName)));

            ILGenerator il = method.GetILGenerator();
            il.DeclareLocal(ReturnImplType);

            il.Emit(OpCodes.Nop);
            foreach (var arg in ConstructorArgs)
            {
                if (arg is IInjectableConstructorArgDefinition)
                {
                    var passedArgument = constructorArgList.FindExisting(arg);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Call, ((IInjectableConstructorArg)passedArgument).Getter);
                }
                else if (arg is IPassedConstructorArgDefinition)
                {
                    il.Emit(OpCodes.Ldarg, ((IPassedConstructorArgDefinition)arg).ParameterIndex + 1);
                }
                else
                {
                    throw new Exception("Unrecognised type of argument: " + arg.GetType().FullName);
                }
            }

            il.Emit(OpCodes.Newobj, conObj);

            il.Emit(OpCodes.Nop);
            il.Emit(OpCodes.Ret);
        }