Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
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;
		}