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