public Tuple <Type, Func <object> > CreateProxyType(Type t, bool compileProxyContructor = true)
        {
            Type                         interceptorType;
            Type                         typeToDerive = t;
            bool                         genericType  = false;
            GeneratedTypeKey             key          = new GeneratedTypeKey(typeToDerive);
            Tuple <Type, Func <object> > tuple;

            if (DerivedClasses.TryGetValue(key, out tuple))
            {
                return(tuple);
            }
            if (t.IsGenericType)
            {
                typeToDerive = t.GetGenericTypeDefinition();
                genericType  = true;
            }
            if (!CanIntercept(t))
            {
                throw new InvalidOperationException(
                          string.Format(CultureInfo.CurrentCulture, Resources.InterceptionNotSupported, t.Name));
            }
            lock (DerivedClasses)
            {
                InterceptingClassGenerator generator = new InterceptingClassGenerator(typeToDerive);
                interceptorType = generator.GenerateType();
                if (genericType)
                {
                    interceptorType = interceptorType.MakeGenericType(t.GetGenericArguments());
                }
                Func <object> contructor = null;
                if (compileProxyContructor)
                {
                    contructor = Expression.Lambda <Func <object> >(Expression.New(interceptorType)).Compile();
                }
                tuple = new Tuple <Type, Func <object> >(interceptorType, contructor);
                DerivedClasses[key] = tuple;
            }
            if (genericType)
            {
                IList <PropertyInfoEx> tableInfo;
                TypePropertiesCache.VerifyInformationIsLoaded(interceptorType, out tableInfo);
            }
            else
            {
                TypePropertiesCache.AssociateTypeWithProxyType(t, interceptorType);
            }
            PropertiesExDictionary dic;

            TypePropertiesCache.cachePropertiesEx.TryGetValue(interceptorType, out dic);
            interceptorType.GetField("__Props").SetValue(null, (PropertyInfoEx[])dic.PropertiesList);
            //PropertyInfoEx[] currentProps;
            //TypePropertiesCache.cachePropertiesEx.TryGetValue(t, out currentProps);
            //TypePropertiesCache.cachePropertiesEx.Remove(t);
            //TypePropertiesCache.cachePropertiesEx.Add(interceptorType, currentProps);
            return(tuple);
        }
示例#2
0
        /// <summary>
        /// Create the wrapper class for the given type.
        /// </summary>
        /// <returns>Wrapper type.</returns>
        public Type GenerateType()
        {
            var props = TypePropertiesCache.GetArrayPropertiesOrderedByIndex(typeToIntercept);

            AddProperties(props);
            AddConstructors();



            ConstructorBuilder staticConstructorBuilder     = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);
            ILGenerator        staticConstructorILGenerator = staticConstructorBuilder.GetILGenerator();

            foreach (var method in methodOverrides)
            {
                if (method.statficfieldForMethodHandle != null)
                {
                    staticConstructorILGenerator.Emit(OpCodes.Ldtoken, method.methodInfoForMethodHandle);
                    if (method.methodToOverride.DeclaringType.IsGenericType)
                    {
                        // if the declaring type is generic, we need to get the method from the target type
                        staticConstructorILGenerator.Emit(OpCodes.Ldtoken, method.targetType);
                        staticConstructorILGenerator.Emit(OpCodes.Call, MethodBaseMethods.GetMethodForGenericFromHandle);
                    }
                    else
                    {
                        staticConstructorILGenerator.Emit(OpCodes.Call, MethodBaseMethods.GetMethodFromHandle);                         // target method
                    }
                }
                staticConstructorILGenerator.Emit(OpCodes.Stsfld, method.statficfieldForMethodHandle);
            }
            staticConstructorILGenerator.Emit(OpCodes.Ret);


            Type result = typeBuilder.CreateType();

            return(result);
        }