protected virtual IEnumerable <Type> GetTypeImplementerMapping(out IEnumerable <ITypeContributor> contributors, INamingScope namingScope) { var methodsToSkip = new List <MethodInfo>(); var proxyInstance = new ClassProxyWithTargetInstanceContributor(targetType, methodsToSkip, additionalInterfacesToProxy, ProxyTypeConstants.ClassWithTarget); // TODO: the trick with methodsToSkip is not very nice... var proxyTarget = new ClassProxyWithTargetTargetContributor(targetType, methodsToSkip, namingScope) { Logger = Logger }; IDictionary <Type, ITypeContributor> typeImplementerMapping = new Dictionary <Type, ITypeContributor>(); // Order of interface precedence: // 1. first target // target is not an interface so we do nothing var targetInterfaces = targetType.GetAllInterfaces(); // 2. then mixins var mixins = new MixinContributor(namingScope, false) { Logger = Logger }; if (ProxyGenerationOptions.HasMixins) { foreach (var mixinInterface in ProxyGenerationOptions.MixinData.MixinInterfaces) { if (targetInterfaces.Contains(mixinInterface)) { // OK, so the target implements this interface. We now do one of two things: if (additionalInterfacesToProxy.Contains(mixinInterface) && typeImplementerMapping.ContainsKey(mixinInterface) == false) { AddMappingNoCheck(mixinInterface, proxyTarget, typeImplementerMapping); proxyTarget.AddInterfaceToProxy(mixinInterface); } // we do not intercept the interface mixins.AddEmptyInterface(mixinInterface); } else { if (!typeImplementerMapping.ContainsKey(mixinInterface)) { mixins.AddInterfaceToProxy(mixinInterface); AddMappingNoCheck(mixinInterface, mixins, typeImplementerMapping); } } } } var additionalInterfacesContributor = new InterfaceProxyWithoutTargetContributor(namingScope, (c, m) => NullExpression.Instance) { Logger = Logger }; // 3. then additional interfaces foreach (var @interface in additionalInterfacesToProxy) { if (targetInterfaces.Contains(@interface)) { if (typeImplementerMapping.ContainsKey(@interface)) { continue; } // we intercept the interface, and forward calls to the target type AddMappingNoCheck(@interface, proxyTarget, typeImplementerMapping); proxyTarget.AddInterfaceToProxy(@interface); } else if (ProxyGenerationOptions.MixinData.ContainsMixin(@interface) == false) { additionalInterfacesContributor.AddInterfaceToProxy(@interface); AddMapping(@interface, additionalInterfacesContributor, typeImplementerMapping); } } // 4. plus special interfaces #if FEATURE_SERIALIZATION if (targetType.IsSerializable) { AddMappingForISerializable(typeImplementerMapping, proxyInstance); } #endif try { AddMappingNoCheck(typeof(IProxyTargetAccessor), proxyInstance, typeImplementerMapping); } catch (ArgumentException) { HandleExplicitlyPassedProxyTargetAccessor(targetInterfaces, additionalInterfacesToProxy); } contributors = new List <ITypeContributor> { proxyTarget, mixins, additionalInterfacesContributor, proxyInstance }; return(typeImplementerMapping.Keys); }
private IEnumerable <Type> GetTypeImplementerMapping( out IEnumerable <ITypeContributor> contributors, INamingScope namingScope ) { var contributorsList = new List <ITypeContributor>(capacity: 5); var targetInterfaces = targetType.GetAllInterfaces(); var typeImplementerMapping = new Dictionary <Type, ITypeContributor>(); // Order of interface precedence: // 1. first target // target is not an interface so we do nothing var targetContributor = GetProxyTargetContributor(namingScope); contributorsList.Add(targetContributor); // 2. then mixins if (ProxyGenerationOptions.HasMixins) { var mixinContributor = new MixinContributor(namingScope, false) { Logger = Logger }; contributorsList.Add(mixinContributor); foreach (var mixinInterface in ProxyGenerationOptions.MixinData.MixinInterfaces) { if (targetInterfaces.Contains(mixinInterface)) { // OK, so the target implements this interface. We now do one of two things: if ( interfaces.Contains(mixinInterface) && typeImplementerMapping.ContainsKey(mixinInterface) == false ) { AddMappingNoCheck( mixinInterface, targetContributor, typeImplementerMapping ); targetContributor.AddInterfaceToProxy(mixinInterface); } // we do not intercept the interface mixinContributor.AddEmptyInterface(mixinInterface); } else { if (!typeImplementerMapping.ContainsKey(mixinInterface)) { mixinContributor.AddInterfaceToProxy(mixinInterface); AddMappingNoCheck( mixinInterface, mixinContributor, typeImplementerMapping ); } } } } // 3. then additional interfaces if (interfaces.Length > 0) { var additionalInterfacesContributor = new InterfaceProxyWithoutTargetContributor( namingScope, (c, m) => NullExpression.Instance ) { Logger = Logger }; contributorsList.Add(additionalInterfacesContributor); foreach (var @interface in interfaces) { if (targetInterfaces.Contains(@interface)) { if (typeImplementerMapping.ContainsKey(@interface)) { continue; } // we intercept the interface, and forward calls to the target type AddMappingNoCheck(@interface, targetContributor, typeImplementerMapping); targetContributor.AddInterfaceToProxy(@interface); } else if (ProxyGenerationOptions.MixinData.ContainsMixin(@interface) == false) { additionalInterfacesContributor.AddInterfaceToProxy(@interface); AddMapping( @interface, additionalInterfacesContributor, typeImplementerMapping ); } } } // 4. plus special interfaces #if FEATURE_SERIALIZATION if (targetType.IsSerializable) { var serializableContributor = GetSerializableContributor(); contributorsList.Add(serializableContributor); AddMappingForISerializable(typeImplementerMapping, serializableContributor); } #endif var proxyTargetAccessorContributor = GetProxyTargetAccessorContributor(); contributorsList.Add(proxyTargetAccessorContributor); try { AddMappingNoCheck( typeof(IProxyTargetAccessor), proxyTargetAccessorContributor, typeImplementerMapping ); } catch (ArgumentException) { HandleExplicitlyPassedProxyTargetAccessor(targetInterfaces); } contributors = contributorsList; return(typeImplementerMapping.Keys); }
protected virtual IEnumerable <Type> GetTypeImplementerMapping(Type[] interfaces, Type proxyTargetType, out IEnumerable <ITypeContributor> contributors, INamingScope namingScope) { IDictionary <Type, ITypeContributor> typeImplementerMapping = new Dictionary <Type, ITypeContributor>(); var mixins = new MixinContributor(namingScope, AllowChangeTarget) { Logger = Logger }; // Order of interface precedence: // 1. first target var targetInterfaces = proxyTargetType.GetAllInterfaces(); var additionalInterfaces = TypeUtil.GetAllInterfaces(interfaces); var target = AddMappingForTargetType(typeImplementerMapping, proxyTargetType, targetInterfaces, additionalInterfaces, namingScope); // 2. then mixins if (ProxyGenerationOptions.HasMixins) { foreach (var mixinInterface in ProxyGenerationOptions.MixinData.MixinInterfaces) { if (targetInterfaces.Contains(mixinInterface)) { // OK, so the target implements this interface. We now do one of two things: if (additionalInterfaces.Contains(mixinInterface)) { // we intercept the interface, and forward calls to the target type AddMapping(mixinInterface, target, typeImplementerMapping); } // we do not intercept the interface mixins.AddEmptyInterface(mixinInterface); } else { if (!typeImplementerMapping.ContainsKey(mixinInterface)) { mixins.AddInterfaceToProxy(mixinInterface); typeImplementerMapping.Add(mixinInterface, mixins); } } } } var additionalInterfacesContributor = GetContributorForAdditionalInterfaces(namingScope); // 3. then additional interfaces foreach (var @interface in additionalInterfaces) { if (typeImplementerMapping.ContainsKey(@interface)) { continue; } if (ProxyGenerationOptions.MixinData.ContainsMixin(@interface)) { continue; } additionalInterfacesContributor.AddInterfaceToProxy(@interface); AddMappingNoCheck(@interface, additionalInterfacesContributor, typeImplementerMapping); } // 4. plus special interfaces var instance = new InterfaceProxyInstanceContributor(targetType, GeneratorType, interfaces); #if FEATURE_SERIALIZATION AddMappingForISerializable(typeImplementerMapping, instance); #endif try { AddMappingNoCheck(typeof(IProxyTargetAccessor), instance, typeImplementerMapping); } catch (ArgumentException) { HandleExplicitlyPassedProxyTargetAccessor(targetInterfaces, additionalInterfaces); } contributors = new List <ITypeContributor> { target, additionalInterfacesContributor, mixins, instance }; return(typeImplementerMapping.Keys); }
protected virtual IEnumerable<Type> GetTypeImplementerMapping(Type[] interfaces, out IEnumerable<ITypeContributor> contributors, INamingScope namingScope) { var methodsToSkip = new List<MethodInfo>(); var proxyInstance = new ClassProxyInstanceContributor(targetType, methodsToSkip, interfaces, ProxyTypeConstants.Class); // TODO: the trick with methodsToSkip is not very nice... var proxyTarget = new ClassProxyTargetContributor(targetType, methodsToSkip, namingScope) { Logger = Logger }; IDictionary<Type, ITypeContributor> typeImplementerMapping = new Dictionary<Type, ITypeContributor>(); // Order of interface precedence: // 1. first target // target is not an interface so we do nothing var targetInterfaces = targetType.GetAllInterfaces(); var additionalInterfaces = TypeUtil.GetAllInterfaces(interfaces); // 2. then mixins var mixins = new MixinContributor(namingScope, false) { Logger = Logger }; if (ProxyGenerationOptions.HasMixins) { foreach (var mixinInterface in ProxyGenerationOptions.MixinData.MixinInterfaces) { if (targetInterfaces.Contains(mixinInterface)) { // OK, so the target implements this interface. We now do one of two things: if (additionalInterfaces.Contains(mixinInterface) && typeImplementerMapping.ContainsKey(mixinInterface) == false) { AddMappingNoCheck(mixinInterface, proxyTarget, typeImplementerMapping); proxyTarget.AddInterfaceToProxy(mixinInterface); } // we do not intercept the interface mixins.AddEmptyInterface(mixinInterface); } else { if (!typeImplementerMapping.ContainsKey(mixinInterface)) { mixins.AddInterfaceToProxy(mixinInterface); AddMappingNoCheck(mixinInterface, mixins, typeImplementerMapping); } } } } var additionalInterfacesContributor = new InterfaceProxyWithoutTargetContributor(namingScope, (c, m) => NullExpression.Instance) { Logger = Logger }; // 3. then additional interfaces foreach (var @interface in additionalInterfaces) { if (targetInterfaces.Contains(@interface)) { if (typeImplementerMapping.ContainsKey(@interface)) continue; // we intercept the interface, and forward calls to the target type AddMappingNoCheck(@interface, proxyTarget, typeImplementerMapping); proxyTarget.AddInterfaceToProxy(@interface); } else if (ProxyGenerationOptions.MixinData.ContainsMixin(@interface) == false) { additionalInterfacesContributor.AddInterfaceToProxy(@interface); AddMapping(@interface, additionalInterfacesContributor, typeImplementerMapping); } } #if !SILVERLIGHT // 4. plus special interfaces if (targetType.IsSerializable) { AddMappingForISerializable(typeImplementerMapping, proxyInstance); } #endif try { AddMappingNoCheck(typeof(IProxyTargetAccessor), proxyInstance, typeImplementerMapping); } catch (ArgumentException ) { HandleExplicitlyPassedProxyTargetAccessor(targetInterfaces, additionalInterfaces); } contributors = new List<ITypeContributor> { proxyTarget, mixins, additionalInterfacesContributor, proxyInstance }; return typeImplementerMapping.Keys; }