Esempio n. 1
0
            public ProxyBuilderContext(ProxyTypeCache cache, Type targetType, Type sourceType)
            {
                Cache = cache;

                Key     = new Tuple <Type, Type>(sourceType, targetType);
                Visited = new Dictionary <Tuple <Type, Type>, VerificationResult>();
            }
        private U Convert <T, U>(object value)
        {
            var cache     = new ProxyTypeCache();
            var proxyType = ProxyTypeEmitter.GetProxyType(cache, typeof(U), typeof(T));

            Assert.NotNull(proxyType);
            var proxy = Activator.CreateInstance(proxyType, value);

            return(Assert.IsAssignableFrom <U>(proxy));
        }
        private object ConvertTo(object value, Type type)
        {
            var cache     = new ProxyTypeCache();
            var proxyType = ProxyTypeEmitter.GetProxyType(cache, type, value.GetType());

            Assert.NotNull(proxyType);
            var proxy = Activator.CreateInstance(proxyType, value);

            Assert.IsAssignableFrom(type, proxy);
            return(proxy);
        }
        public void GetProxyType_Assignable(Type sourceType, Type targetType)
        {
            // Arrange
            var cache = new ProxyTypeCache();

            // Act
            var result = ProxyTypeEmitter.GetProxyType(cache, targetType, sourceType);

            // Assert
            Assert.Null(result);
        }
        public void GetProxyType_Identity(Type type)
        {
            // Arrange
            var cache = new ProxyTypeCache();

            // Act
            var result = ProxyTypeEmitter.GetProxyType(cache, type, type);

            // Assert
            Assert.Null(result);
        }
        public void GetProxyType_IfAlreadyInCache_AlsoAddedToVisited_FromError()
        {
            // Arrange
            var targetType = typeof(IPerson);
            var sourceType = typeof(Person);

            var key   = new Tuple <Type, Type>(sourceType, targetType);
            var cache = new ProxyTypeCache();

            cache[key] = ProxyTypeCacheResult.FromError(key, "Test Error");

            var context = new ProxyTypeEmitter.ProxyBuilderContext(cache, targetType, sourceType);

            // Act
            var result = ProxyTypeEmitter.VerifyProxySupport(context, key);

            // Assert
            Assert.False(result);
            Assert.Equal(key, context.Visited.Single().Key);
        }
        public void GetProxyType_IfAlreadyInCache_AlsoAddedToVisited_FromType()
        {
            // Arrange
            var targetType = typeof(IPerson);
            var sourceType = typeof(Person);

            var key   = new Tuple <Type, Type>(sourceType, targetType);
            var cache = new ProxyTypeCache();

            cache[key] = ProxyTypeCacheResult.FromType(key, sourceType, sourceType.GetConstructor(Array.Empty <Type>()));

            var context = new ProxyTypeEmitter.ProxyBuilderContext(cache, targetType, sourceType);

            // Act
            var result  = ProxyTypeEmitter.VerifyProxySupport(context, key);
            var result2 = ProxyTypeEmitter.VerifyProxySupport(context, key);

            // Assert
            Assert.True(result);
            Assert.True(result2);
            Assert.Single(context.Visited);
            Assert.Equal(key, context.Visited.Single().Key);
        }
Esempio n. 8
0
        public static Type GetProxyType(ProxyTypeCache cache, Type targetType, Type sourceType)
        {
            if (targetType.GetTypeInfo().IsAssignableFrom(sourceType.GetTypeInfo()))
            {
                return(null);
            }

            var key = new Tuple <Type, Type>(sourceType, targetType);

            ProxyTypeCacheResult result;

            if (!cache.TryGetValue(key, out result))
            {
                var context = new ProxyBuilderContext(cache, targetType, sourceType);

                // Check that all required types are proxy-able - this will create the TypeBuilder, Constructor,
                // and property mappings.
                //
                // We need to create the TypeBuilder and Constructor up front to deal with cycles that can occur
                // when generating the proxy properties.
                if (!VerifyProxySupport(context, context.Key))
                {
                    var error = cache[key];
                    Debug.Assert(error != null && error.IsError);
                    throw new InvalidOperationException(error.Error);
                }

                Debug.Assert(context.Visited.ContainsKey(context.Key));

                // Now that we've generated all of the constructors for the proxies, we can generate the properties.
                foreach (var verificationResult in context.Visited)
                {
                    if (verificationResult.Value.Mappings != null)
                    {
                        AddProperties(
                            context,
                            verificationResult.Value.TypeBuilder,
                            verificationResult.Value.Mappings);
                    }
                }

                // Now generate the type
                foreach (var verificationResult in context.Visited)
                {
                    if (verificationResult.Value.TypeBuilder != null)
                    {
                        verificationResult.Value.Type = verificationResult.Value.TypeBuilder.CreateTypeInfo().AsType();
                    }
                }

                // We only want to publish the results after all of the proxies are totally generated.
                foreach (var verificationResult in context.Visited)
                {
                    cache[verificationResult.Key] = ProxyTypeCacheResult.FromType(
                        verificationResult.Key,
                        verificationResult.Value.Type,
                        verificationResult.Value.Constructor);
                }

                return(context.Visited[context.Key].Type);
            }
            else if (result.IsError)
            {
                throw new InvalidOperationException(result.Error);
            }
            else if (result.Type == null)
            {
                // This is an identity convertion
                return(null);
            }
            else
            {
                return(result.Type);
            }
        }