Example #1
0
        /// <inheritdoc />
        public override TypeInfo Generate()
        {
            // Create backing field as:
            // private string assemblyName;
            var assemblyNameField =
                DynamicTypeBuilder.DefineField("assemblyName", typeof(string), FieldAttributes.Private);

            // Create ctor as:
            // public IgnoresAccessChecksToAttribute(string)
            var constructorBuilder = DynamicTypeBuilder.DefineConstructor(MethodAttributes.Public,
                                                                          CallingConventions.HasThis,
                                                                          new[] { assemblyNameField.FieldType });

            var il = constructorBuilder.GetILGenerator();

            // Create ctor body as:
            // this.assemblyName = {ctor parameter 0}
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg, 1);
            il.Emit(OpCodes.Stfld, assemblyNameField);

            // return
            il.Emit(OpCodes.Ret);

            // Define property as:
            // public string AssemblyName {get { return this.assemblyName; } }

            // ReSharper disable once UnusedVariable
            var getterPropertyBuilder = DynamicTypeBuilder.DefineProperty(
                "AssemblyName",
                PropertyAttributes.None,
                CallingConventions.HasThis,
                returnType: typeof(string),
                parameterTypes: null);

            var getterMethodBuilder = DynamicTypeBuilder.DefineMethod(
                "get_AssemblyName",
                MethodAttributes.Public,
                CallingConventions.HasThis,
                returnType: typeof(string),
                parameterTypes: null);

            // Generate body:
            // return this.assemblyName;
            il = getterMethodBuilder.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, assemblyNameField);
            il.Emit(OpCodes.Ret);

            // Generate the AttributeUsage attribute for this attribute type:
            // [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
            var attributeUsageTypeInfo = typeof(AttributeUsageAttribute).GetTypeInfo();

            // Find the ctor that takes only AttributeTargets
            var attributeUsageConstructorInfo =
                attributeUsageTypeInfo.DeclaredConstructors
                .Single(c => c.GetParameters().Length == 1 &&
                        c.GetParameters()[0].ParameterType == typeof(AttributeTargets));

            // Find the property to set AllowMultiple
            var allowMultipleProperty =
                attributeUsageTypeInfo.DeclaredProperties
                .Single(f => string.Equals(f.Name, "AllowMultiple"));

            // Create a builder to construct the instance via the ctor and property
            var customAttributeBuilder =
                new CustomAttributeBuilder(attributeUsageConstructorInfo,
                                           new object[] { AttributeTargets.Assembly },
                                           new[] { allowMultipleProperty },
                                           new object[] { true });

            // Attach this attribute instance to the newly defined attribute type
            DynamicTypeBuilder.SetCustomAttribute(customAttributeBuilder);

            // Make the TypeInfo real so the constructor can be used.
            return(DynamicTypeBuilder.CreateTypeInfo());
        }
        public void Inject(Type entityType, DynamicAssemblyBuilder assemblyBuilder, DynamicTypeBuilder typeBuilder)
        {
            var propertyBuilder = typeBuilder.DefineProperty("_id", typeof(ObjectId));

            propertyBuilder.DefineGetSetMethods();
        }
        /// <summary>
        /// Добавляет реализацию интерфейса к прокси.
        /// </summary>
        /// <param name="interfaceType">Тип интерфейса.</param>
        public void ImplementInterface(Type interfaceType)
        {
            // Если необходимо - добавляем в сборку атрибут игнорирующий модификаторы доступа
            _proxyAssembly.EnsureTypeVisible(interfaceType);

            DynamicTypeBuilder.AddInterfaceImplementation(interfaceType);

            // AccessorMethods -> Metadata mappings.
            var propertyMap = new Dictionary <MethodInfo, PropertyAccessor>(MethodEqualityComparer.Instance);

            foreach (var pi in interfaceType.GetRuntimeProperties())
            {
                var ai = new PropertyAccessor(pi.GetMethod, pi.SetMethod);
                if (pi.GetMethod != null)
                {
                    propertyMap[pi.GetMethod] = ai;
                }
                if (pi.SetMethod != null)
                {
                    propertyMap[pi.SetMethod] = ai;
                }
            }

            var eventMap = new Dictionary <MethodInfo, EventAccessor>(MethodEqualityComparer.Instance);

            foreach (var ei in interfaceType.GetRuntimeEvents())
            {
                var ai = new EventAccessor(ei.AddMethod, ei.RemoveMethod, ei.RaiseMethod);
                if (ei.AddMethod != null)
                {
                    eventMap[ei.AddMethod] = ai;
                }
                if (ei.RemoveMethod != null)
                {
                    eventMap[ei.RemoveMethod] = ai;
                }
                if (ei.RaiseMethod != null)
                {
                    eventMap[ei.RaiseMethod] = ai;
                }
            }

            foreach (var mi in interfaceType.GetRuntimeMethods())
            {
                var mdb = ImplementMethod(mi);
                if (propertyMap.TryGetValue(mi, out var associatedProperty))
                {
                    if (MethodEqualityComparer.Instance.Equals(associatedProperty.InterfaceGetMethod, mi))
                    {
                        associatedProperty.GetMethodBuilder = mdb;
                    }
                    else
                    {
                        associatedProperty.SetMethodBuilder = mdb;
                    }
                }

                // ReSharper disable once InvertIf
                if (eventMap.TryGetValue(mi, out var associatedEvent))
                {
                    if (MethodEqualityComparer.Instance.Equals(associatedEvent.InterfaceAddMethod, mi))
                    {
                        associatedEvent.AddMethodBuilder = mdb;
                    }
                    else if (MethodEqualityComparer.Instance.Equals(associatedEvent.InterfaceRemoveMethod, mi))
                    {
                        associatedEvent.RemoveMethodBuilder = mdb;
                    }
                    else
                    {
                        associatedEvent.RaiseMethodBuilder = mdb;
                    }
                }
            }

            foreach (var pi in interfaceType.GetRuntimeProperties())
            {
                var ai = propertyMap[pi.GetMethod ?? pi.SetMethod];
                var pb = DynamicTypeBuilder.DefineProperty(pi.Name, pi.Attributes, pi.PropertyType,
                                                           pi.GetIndexParameters().Select(p => p.ParameterType).ToArray());
                if (ai.GetMethodBuilder != null)
                {
                    pb.SetGetMethod(ai.GetMethodBuilder);
                }
                if (ai.SetMethodBuilder != null)
                {
                    pb.SetSetMethod(ai.SetMethodBuilder);
                }
            }

            foreach (var ei in interfaceType.GetRuntimeEvents())
            {
                var ai = eventMap[ei.AddMethod ?? ei.RemoveMethod];
                var eb = DynamicTypeBuilder.DefineEvent(ei.Name, ei.Attributes, ei.EventHandlerType);
                if (ai.AddMethodBuilder != null)
                {
                    eb.SetAddOnMethod(ai.AddMethodBuilder);
                }
                if (ai.RemoveMethodBuilder != null)
                {
                    eb.SetRemoveOnMethod(ai.RemoveMethodBuilder);
                }
                if (ai.RaiseMethodBuilder != null)
                {
                    eb.SetRaiseMethod(ai.RaiseMethodBuilder);
                }
            }
        }