public ProxyTypeBuilder(ClrEntityType ospaceEntityType)
 {
     _ospaceEntityType = ospaceEntityType;
     _baseImplementor = new BaseProxyImplementor();
     _ipocoImplementor = new IPOCOImplementor(ospaceEntityType);
     _lazyLoadImplementor = new LazyLoadImplementor(ospaceEntityType);
     _dataContractImplementor = new DataContractImplementor(ospaceEntityType);
     _iserializableImplementor = new ISerializableImplementor(ospaceEntityType);
 }
        public bool EmitMember(TypeBuilder typeBuilder, EdmMember member, PropertyBuilder propertyBuilder, PropertyInfo baseProperty, BaseProxyImplementor baseImplementor)
        {
            if (_members.Contains(member))
            {
                MethodInfo baseGetter = baseProperty.GetGetMethod(true);
                const MethodAttributes getterAttributes = MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual;
                MethodAttributes getterAccess = baseGetter.Attributes & MethodAttributes.MemberAccessMask;

                // Define field to store interceptor Func
                // Signature of interceptor Func delegate is as follows:
                //
                //    bool intercept(ProxyType proxy, PropertyType propertyValue)
                //
                // where
                //     PropertyType is the type of the Property, such as ICollection<Customer>,
                //     ProxyType is the type of the proxy object,
                //     propertyValue is the value returned from the proxied type's property getter.

                Type interceptorType = typeof(Func<,,>).MakeGenericType(typeBuilder, baseProperty.PropertyType, typeof(bool));
                MethodInfo interceptorInvoke = TypeBuilder.GetMethod(interceptorType, typeof(Func<,,>).GetMethod("Invoke"));
                FieldBuilder interceptorField = typeBuilder.DefineField(GetInterceptorFieldName(baseProperty.Name), interceptorType, FieldAttributes.Private | FieldAttributes.Static);

                // Define a property getter override in the proxy type
                MethodBuilder getterBuilder = typeBuilder.DefineMethod("get_" + baseProperty.Name, getterAccess | getterAttributes, baseProperty.PropertyType, Type.EmptyTypes);
                ILGenerator generator = getterBuilder.GetILGenerator();

                // Emit instructions for the following call:
                //   T value = base.SomeProperty;
                //   if(this._interceptorForSomeProperty(this, value))
                //   {  return value; }
                //   return base.SomeProperty;
                // where _interceptorForSomeProperty represents the interceptor Func field.

                Label lableTrue = generator.DefineLabel();
                generator.DeclareLocal(baseProperty.PropertyType);       // T value
                generator.Emit(OpCodes.Ldarg_0);            // call base.SomeProperty
                generator.Emit(OpCodes.Call, baseGetter); // call to base property getter
                generator.Emit(OpCodes.Stloc_0);            // value = result
                generator.Emit(OpCodes.Ldarg_0);            // load this
                generator.Emit(OpCodes.Ldfld, interceptorField); // load this._interceptor
                generator.Emit(OpCodes.Ldarg_0);            // load this
                generator.Emit(OpCodes.Ldloc_0);            // load value
                generator.Emit(OpCodes.Callvirt, interceptorInvoke); // call to interceptor delegate with (this, value)
                generator.Emit(OpCodes.Brtrue_S, lableTrue); // if true, just return
                generator.Emit(OpCodes.Ldarg_0); // else, call the base propertty getter again
                generator.Emit(OpCodes.Call, baseGetter); // call to base property getter
                generator.Emit(OpCodes.Ret);
                generator.MarkLabel(lableTrue);
                generator.Emit(OpCodes.Ldloc_0);
                generator.Emit(OpCodes.Ret);

                propertyBuilder.SetGetMethod(getterBuilder);

                baseImplementor.AddBasePropertyGetter(baseProperty);
                return true;
            }
            return false;
        }
 public bool EmitMember(TypeBuilder typeBuilder, EdmMember member, PropertyBuilder propertyBuilder, PropertyInfo baseProperty, BaseProxyImplementor baseImplementor)
 {
     if (_scalarMembers.Contains(member))
     {
         bool isKeyMember = _ospaceEntityType.KeyMembers.Contains(member.Identity);
         EmitScalarSetter(typeBuilder, propertyBuilder, baseProperty, isKeyMember);
         return true;
     }
     else if (_relationshipMembers.Contains(member))
     {
         Debug.Assert(member != null, "member is null");
         Debug.Assert(member.BuiltInTypeKind == BuiltInTypeKind.NavigationProperty);
         NavigationProperty navProperty = member as NavigationProperty;
         if (navProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many)
         {
             EmitCollectionProperty(typeBuilder, propertyBuilder, baseProperty, navProperty);
         }
         else
         {
             EmitReferenceProperty(typeBuilder, propertyBuilder, baseProperty, navProperty);
         }
         baseImplementor.AddBasePropertySetter(baseProperty);
         return true;
     }
     return false;
 }