예제 #1
0
        void CreateSaverIl(IILGen ilGen, IEnumerable <TableFieldInfo> fields,
                           Action <IILGen> pushInstance, Action <IILGen> pushRelationIface,
                           Action <IILGen> pushWriter, Action <IILGen> pushTransaction)
        {
            var      anyNeedsCtx    = fields.Any(tfi => tfi.Handler.NeedsCtx());
            IILLocal writerCtxLocal = null;

            if (anyNeedsCtx)
            {
                writerCtxLocal = ilGen.DeclareLocal(typeof(IWriterCtx));
                ilGen
                .Do(pushTransaction)
                .Do(pushWriter)
                .Newobj(() => new DBWriterCtx(null, null))
                .Stloc(writerCtxLocal);
            }
            var props = ClientType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

            foreach (var field in fields)
            {
                var             getter = props.First(p => GetPersistentName(p) == field.Name).GetGetMethod(true);
                Action <IILGen> writerOrCtx;
                var             handler = field.Handler.SpecializeSaveForType(getter.ReturnType);
                if (handler.NeedsCtx())
                {
                    writerOrCtx = il => il.Ldloc(writerCtxLocal);
                }
                else
                {
                    writerOrCtx = pushWriter;
                }
                MethodInfo apartFieldGetter = null;
                if (pushRelationIface != null)
                {
                    ApartFields.TryGetValue(field.Name, out apartFieldGetter);
                }
                handler.Save(ilGen, writerOrCtx, il =>
                {
                    if (apartFieldGetter != null)
                    {
                        il.Do(pushRelationIface);
                        getter = apartFieldGetter;
                    }
                    else
                    {
                        il.Do(pushInstance);
                    }
                    il.Callvirt(getter);
                    _relationInfoResolver.TypeConvertorGenerator.GenerateConversion(getter.ReturnType,
                                                                                    handler.HandledType())(il);
                });
            }
        }
예제 #2
0
        Action <IInternalObjectDBTransaction, AbstractBufferedWriter, object, object> CreateSaverWithApartFields(
            IEnumerable <TableFieldInfo> fields, string saverName)
        {
            var method = ILBuilder.Instance.NewMethod <
                Action <IInternalObjectDBTransaction, AbstractBufferedWriter, object, object> >(saverName);
            var ilGenerator = method.Generator;

            ilGenerator.DeclareLocal(ClientType);
            StoreNthArgumentOfTypeIntoLoc(ilGenerator, 2, ClientType, 0);
            var hasApartFields = ApartFields.Any();

            if (hasApartFields)
            {
                ilGenerator.DeclareLocal(_interfaceType);
                StoreNthArgumentOfTypeIntoLoc(ilGenerator, 3, _interfaceType, 1);
            }
            CreateSaverIl(ilGenerator, fields,
                          il => il.Ldloc(0), hasApartFields ? il => il.Ldloc(1) : (Action <IILGen>)null,
                          il => il.Ldarg(1), il => il.Ldarg(0));
            ilGenerator
            .Ret();
            return(method.Create());
        }