public static Type CreateProxy(ModuleBuilder module, Type type)
        {
            if (module == null)
            {
                throw new ArgumentNullException(nameof(module));
            }
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            var tb = module.DefineType($"{type.FullName}@Proxy@{type.Assembly.GetHashCode()}", TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NotPublic);

            var cacheType = CacheTypeResolver.Resolve(type);
            var fb        = MakeField(tb, cacheType);

            foreach (var method in cacheType.Methods)
            {
                var mb = tb.DefineMethod(method.Method.Name,
                                         type.IsInterface
                        ? MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot
                        : MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig,
                                         method.Method.ReturnType,
                                         method.Method.GetParameters().Select(p => p.ParameterType).ToArray());
                var il = mb.GetILGenerator();

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, fb);
                il.Emit(OpCodes.Ldarg_1);

                switch (method.Operation)
                {
                case CacheOperation.Get:
                    BuildGet(method, il, cacheType.DefaultTtl);
                    break;

                case CacheOperation.Set:
                    BuildSet(method, il, cacheType.DefaultTtl);
                    break;

                case CacheOperation.Remove:
                    BuildRemove(method, il);
                    break;

                default:
                    throw new InvalidOperationException($"{mb.Name}不支持的操作{method.Operation}");
                }

                il.Emit(OpCodes.Ret);

                if (type.IsInterface)
                {
                    tb.DefineMethodOverride(mb, method.Method);
                }
            }
#if NETSTANDARD2_0
            return(tb.CreateTypeInfo() !);
#else
            return(tb.CreateType() !);
#endif
        }
Exemple #2
0
        private Type CreateProxy(ModuleBuilder module, Type type)
        {
            if (module == null)
            {
                throw new ArgumentNullException(nameof(module));
            }
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            var proxyType = module.DefineType($"{type.FullName}@Proxy@{type.Assembly.GetHashCode()}", TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NotPublic);
#endif
            var cacheType = CacheTypeResolver.Resolve(type);
            var filed     = proxyType.DefineField("_helper", typeof(CacheHelper), FieldAttributes.Private | FieldAttributes.InitOnly);

            BuildConstructors(proxyType, cacheType, filed);

            foreach (var method in cacheType.Methods)
            {
                var mb = proxyType.DefineMethod(method.Method.Name,
                                                type.IsInterface
                        ? MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.NewSlot
                        : MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
                                                method.Method.ReturnType,
                                                method.Method.GetParameters().Select(p => p.ParameterType).ToArray());

                var il = mb.GetILGenerator();

                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, filed);
                il.Emit(OpCodes.Ldarg_1);

                DefineGenericParameters(mb, method.Method);

                switch (method.Operation)
                {
                case CacheOperation.Get:
                    BuildGet(method, il, cacheType.DefaultTtl);
                    break;

                case CacheOperation.Set:
                    BuildSet(method, il, cacheType.DefaultTtl);
                    break;

                case CacheOperation.Remove:
                    BuildRemove(method, il);
                    break;

                default:
                    throw new InvalidOperationException($"{mb.Name}不支持的操作{method.Operation}");
                }

                il.Emit(OpCodes.Ret);
#if !BuildTask
                if (type.IsInterface)
                {
                    proxyType.DefineMethodOverride(mb, method.Method);
                }
#endif
                BuildParameters(mb.DefineParameter, method.Method.GetParameters());
            }
#if BuildTask
            return(proxyType);
#elif NETSTANDARD2_0
            return(proxyType.CreateTypeInfo() !);
#else
            return(proxyType.CreateType() !);
#endif
        }