Пример #1
0
        internal void AddInterfaceImpl(Type iface)
        {
            // If necessary, generate an attribute to permit visibility
            // to internal types.
            _assembly.EnsureTypeIsVisible(iface);

            _tb.AddInterfaceImplementation(iface);

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

            foreach (var pi in iface.GetRuntimeProperties())
            {
                var ai = new PropertyAccessorInfo(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, EventAccessorInfo>(MethodInfoEqualityComparer.Instance);

            foreach (var ei in iface.GetRuntimeEvents())
            {
                var ai = new EventAccessorInfo(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 iface.GetRuntimeMethods())
            {
                var mdb = AddMethodImpl(mi);
                if (propertyMap.TryGetValue(mi, out var associatedProperty))
                {
                    if (MethodInfoEqualityComparer.Instance.Equals(associatedProperty.InterfaceGetMethod, mi))
                    {
                        associatedProperty.GetMethodBuilder = mdb;
                    }
                    else
                    {
                        associatedProperty.SetMethodBuilder = mdb;
                    }
                }

                if (eventMap.TryGetValue(mi, out var associatedEvent))
                {
                    if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceAddMethod, mi))
                    {
                        associatedEvent.AddMethodBuilder = mdb;
                    }
                    else if (MethodInfoEqualityComparer.Instance.Equals(associatedEvent.InterfaceRemoveMethod, mi))
                    {
                        associatedEvent.RemoveMethodBuilder = mdb;
                    }
                    else
                    {
                        associatedEvent.RaiseMethodBuilder = mdb;
                    }
                }
            }

            foreach (var pi in iface.GetRuntimeProperties())
            {
                var ai = propertyMap[pi.GetMethod ?? pi.SetMethod];
                var pb = _tb.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 iface.GetRuntimeEvents())
            {
                var ai = eventMap[ei.AddMethod ?? ei.RemoveMethod];
                var eb = _tb.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);
                }
            }
        }