/// <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); } } }