Ejemplo n.º 1
0
        public void EmitConstructorBody(TypeBuilder typeBuilder, EmitGenerator gen)
        {
            var mergerType = DefineParameterMergerField(typeBuilder);
            var mergerCtor = GetParameterMergerConstructor(mergerType);

            gen.LoadThis();
            gen.LoadArgument(1);
            gen.New(mergerCtor);
            gen.StoreField(_paramMergerField);
        }
Ejemplo n.º 2
0
        public void EmitConstructorBody(TypeBuilder typeBuilder, EmitGenerator gen, int ctorArgumentIndex, ref int memberParameterIndex)
        {
            var fieldType = DefineParameterField(typeBuilder, memberParameterIndex);

            gen.LoadThis();
            gen.LoadArgument(ctorArgumentIndex);
            gen.LoadArrayElement(memberParameterIndex);
            gen.CastAny(fieldType);
            gen.StoreField(_paramField);

            memberParameterIndex += 1;
        }
Ejemplo n.º 3
0
        public void EmitExecuteMethodBody(EmitGenerator gen, LocalBuilder instance)
        {
            // Use MakeByRefType(), because this is an out (ref) parameter in the method signature.
            var paramType  = _dependencyProvider.TargetType.MakeByRefType();
            var paramTypes = new Type[] { typeof(InjectionContext), paramType };

            var createObjectMethod = _paramField.FieldType.GetMethod("CreateObject", paramTypes);

            if (createObjectMethod == null)
            {
                throw new ImpossibleException();
            }

            _paramValue = gen.DeclareLocal(_dependencyProvider.TargetType);
            gen.LoadThis();
            gen.LoadField(_paramField);
            gen.LoadArgument(1);
            gen.LoadLocalAddress(_paramValue);
            gen.CallMethod(createObjectMethod);
        }
Ejemplo n.º 4
0
        public void EmitExecuteMethodBody(EmitGenerator gen, LocalBuilder instance)
        {
            if (_dependencyProviders == null || _dependencyProviders.Length == 0)
            {
                //var dummyClass = new DummyClass();
                gen.New(_injectedCtor);
                gen.StoreLocal(instance);
            }
            else
            {
                //IObjectRegistration p1;
                //IConfigurationModule p2;
                //ILifetimeScope p3;
                //_parameterMerger.Merge(context, out p1, out p2, out p3);
                //instance = new DummyClass(p1, p2, p3);

                var mergeMethod = _paramMergerField.FieldType.GetMethod("Merge");
                if (mergeMethod == null)
                {
                    throw new ImpossibleException();
                }

                #region Define Locals

                //IObjectRegistration p1;
                //IConfigurationModule p2;
                //ILifetimeScope p3;
                var ctorParamBuilders = new LocalBuilder[_dependencyProviders.Length];
                for (int i = 0; i < _dependencyProviders.Length; i++)
                {
                    ctorParamBuilders[i] = gen.DeclareLocal(_dependencyProviders[i].TargetType);
                }

                #endregion

                #region _parameterMerger.Merge(context, out p1, out p2, out p3);

                gen.LoadThis();
                gen.LoadField(_paramMergerField);
                gen.LoadArgument(1);
                for (int i = 0; i < ctorParamBuilders.Length; i++)
                {
                    gen.LoadLocalAddress(ctorParamBuilders[i]);
                }

                gen.CallMethod(mergeMethod);

                #endregion

                #region instance = new DummyClass(p1, p2, p3);

                for (int i = 0; i < ctorParamBuilders.Length; i++)
                {
                    gen.LoadLocal(ctorParamBuilders[i]);
                }

                gen.New(_injectedCtor);
                gen.StoreLocal(instance);

                #endregion
            }
        }
        static void EmitMergeMethodBody(EmitGenerator gen, GenericTypeParameterBuilder[] genParamBuilders,
                                        FieldBuilder[] depProviderFields)
        {
            // var myParams = context.Parameters;
            var myParams = gen.DeclareLocal(ParameterSetType);

            gen.LoadArgument(1);
            gen.CallMethod(GetInjectionContextParameters);
            gen.StoreLocal(myParams);

            #region If (myParams == null || myParams.Length == 0) condition

            // if (myParams == null || myParams.Length == 0) Goto myParamsIsNullLabel Else Goto myParamsIsNotNullAndLengthNotEqualTo0Label
            var myParamsIsNullLabel = gen.DefineLabel();
            var myParamsIsNotNullAndLengthNotEqualTo0Label = gen.DefineLabel();

            gen.LoadLocal(myParams);
            gen.IfFalseGoto(myParamsIsNullLabel);

            gen.LoadLocal(myParams);
            gen.CallMethod(GetParameterLength);
            gen.IfTrueGoto(myParamsIsNotNullAndLengthNotEqualTo0Label);

            #endregion

            var createObjectMethods = new MethodInfo[depProviderFields.Length];

            #region if (myParams == null || myParams.Length == 0) block

            gen.MarkLabel(myParamsIsNullLabel);
            for (int i = 0; i < depProviderFields.Length; i++)
            {
                // _dependency0.CreateObject(context, out param0);
                // _dependency1.CreateObject(context, out param1);
                // ...
                var depProviderField = depProviderFields[i];
                gen.LoadThis();
                gen.LoadField(depProviderField);
                gen.LoadArgument(1);     // load parameter [context]
                gen.LoadArgument(i + 2); // load parameter [param0], [param1], [param2]...
                var createObjectMethod = GetCreateObjectOfDependencyProviderMethod(depProviderField.FieldType);
                createObjectMethods[i] = createObjectMethod;
                gen.CallMethod(createObjectMethod);
            }

            gen.Return();

            #endregion

            #region if (myParams != null && myParams.Length != 0) block

            gen.MarkLabel(myParamsIsNotNullAndLengthNotEqualTo0Label);

            // var paramKind = myParams.ParameterKind;
            var paramKind = gen.DeclareLocal(typeof(ParameterKind));
            gen.LoadLocal(myParams);
            gen.CallMethod(GetParameterKind);
            gen.StoreLocal(paramKind);

            // (Ok)=====================================================

            var paramKindDefaultCase = gen.DefineLabel();
            var paramKindTable       = new Label[] { gen.DefineLabel(), gen.DefineLabel() };

            gen.LoadLocal(paramKind);
            gen.Switch(paramKindTable); // switch (paramKind)
            // case default Goto paramKindDefaultCase
            gen.Goto(paramKindDefaultCase);

            // (Ok)=====================================================

            #region case paramKind = ParameterKind.Positional (Ok)

            gen.MarkLabel(paramKindTable[0]);

            // var myParamLength = myParams.Length;
            var myParamLength = gen.DeclareLocal(typeof(int));
            gen.LoadLocal(myParams);
            gen.CallMethod(GetParameterLength);
            gen.StoreLocal(myParamLength);

            // switch (myParamLength)
            gen.LoadLocal(myParamLength);
            gen.LoadInt32(1);
            gen.Substrate(); // myParamLength - 1, this is because the switch branch is starting from 1, instead of 0

            var paramLengthDefaultCase = gen.DefineLabel();
            var paramLengthTable       = new Label[depProviderFields.Length];
            for (int i = 0; i < depProviderFields.Length; i++)
            {
                paramLengthTable[i] = gen.DefineLabel();
            }

            gen.Switch(paramLengthTable);
            // case default Goto paramLengthDefaultCase
            gen.Goto(paramLengthDefaultCase);

            #region case i for myParamLength

            for (int i = 0; i < depProviderFields.Length; i++)
            {
                gen.MarkLabel(paramLengthTable[i]);
                for (int j = 0; j < depProviderFields.Length; j++)
                {
                    if (j <= i)
                    {
                        // something like: param0 = GetPositionalDependencyObject(_depProvider0, myParams[0], context);
                        // load _depProvider0
                        gen.LoadThis();
                        gen.LoadField(depProviderFields[j]);

                        // load myParams[0]
                        gen.LoadLocal(myParams);
                        gen.LoadInt32(j);
                        gen.CallMethod(GetItem);

                        // load context
                        gen.LoadArgument(1);

                        var genParamType = genParamBuilders[j];
                        gen.CallMethod(OpenGetPositionalDependencyObjectMethod.MakeGenericMethod(genParamType));
                        //gen.StoreObject(genParamType);
                        gen.StoreArgument(j + 2);
                    }
                    else
                    {
                        // something like: _depProvider1.CreateObject(context, out param1);
                        // load _depProvider1
                        gen.LoadThis();
                        gen.LoadField(depProviderFields[j]);
                        // load context
                        gen.LoadArgument(1);
                        // load param1, its index is j + 2
                        gen.LoadArgument(j + 2);
                        gen.CallMethod(createObjectMethods[j]);
                    }
                }
                gen.Return();
            }

            #endregion

            #region default case for myParamLength

            gen.MarkLabel(paramLengthDefaultCase);
            gen.LoadArgument(1);
            gen.LoadInt32(depProviderFields.Length);
            gen.LoadLocal(myParams);
            gen.CallMethod(GetParameterLength);
            gen.CallMethod(ParameterNumberExceedsMethod);
            gen.Throw();

            #endregion

            gen.Return();

            #endregion

            #region case paramKind = ParameterKind.Named (Ok)

            gen.MarkLabel(paramKindTable[1]);
            for (int i = 0; i < depProviderFields.Length; i++)
            {
                // something like: param0 = GetNamedDependencyObject(_depProvider0, myParams, context);

                // load _depProvider0
                gen.LoadThis();
                //gen.LoadThis(); // why do we need this?
                gen.LoadField(depProviderFields[i]);

                // load myParams
                gen.LoadLocal(myParams);

                // load context
                gen.LoadArgument(1);

                var genParamType = genParamBuilders[i];
                gen.CallMethod(OpenGetNamedDependencyObjectMethod.MakeGenericMethod(genParamType));

                // store to param0, its parameter index is [i + 2]
                gen.StoreArgument(i + 2);
            }
            gen.Return();

            #endregion

            #region default case for ParameterKind (Ok)

            gen.MarkLabel(paramKindDefaultCase);
            gen.Throw(ImpossibleExceptionConstructor);

            #endregion

            gen.Return();

            #endregion
        }