internal ProxyBuilder( ProxyAssembly assembly, TypeBuilder tb, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] Type proxyBaseType) { _assembly = assembly; _tb = tb; _proxyBaseType = proxyBaseType; _fields = new List <FieldBuilder>(); _fields.Add(tb.DefineField("_methodInfos", typeof(MethodInfo[]), FieldAttributes.Private)); _methodInfos = new List <MethodInfo>(); _assembly.EnsureTypeIsVisible(proxyBaseType); }
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()) { // 排除静态方法 if (mi.IsStatic) { continue; } 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); } } }
internal void AddInterfaceImpl([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] 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>(); foreach (PropertyInfo 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>(); foreach (EventInfo 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 (MethodInfo mi in iface.GetRuntimeMethods()) { // Skip regular/non-virtual instance methods, static methods, and methods that cannot be overriden // ("methods that cannot be overriden" includes default implementation of other interface methods). if (!mi.IsVirtual || mi.IsFinal) { continue; } int methodInfoIndex = _methodInfos.Count; _methodInfos.Add(mi); MethodBuilder mdb = AddMethodImpl(mi, methodInfoIndex); if (propertyMap.TryGetValue(mi, out PropertyAccessorInfo? associatedProperty)) { if (mi.Equals(associatedProperty.InterfaceGetMethod)) { associatedProperty.GetMethodBuilder = mdb; } else { associatedProperty.SetMethodBuilder = mdb; } } if (eventMap.TryGetValue(mi, out EventAccessorInfo? associatedEvent)) { if (mi.Equals(associatedEvent.InterfaceAddMethod)) { associatedEvent.AddMethodBuilder = mdb; } else if (mi.Equals(associatedEvent.InterfaceRemoveMethod)) { associatedEvent.RemoveMethodBuilder = mdb; } else { associatedEvent.RaiseMethodBuilder = mdb; } } } foreach (PropertyInfo pi in iface.GetRuntimeProperties()) { PropertyAccessorInfo ai = propertyMap[pi.GetMethod ?? pi.SetMethod !];