示例#1
0
        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;
		}