public ModuleBuilder GetModuleBuilder()
        {
            if (_moduleBuilder == null)
            {
                lock (_lock)
                {
                    if (_moduleBuilder == null)
                    {
                        var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(DynamicAssemblyName,
                                                                                    AssemblyBuilderAccess.Run);
                        _moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");

                        IgnoresAccessChecksToAttributeGenerator.Generate(assemblyBuilder, _moduleBuilder);
                    }
                }
            }

            return(_moduleBuilder);
        }
        private Type CreateProxyType(Type interfaceType)
        {
            if (_moduleBuilder == null)
            {
                lock (_lock)
                {
                    if (_moduleBuilder == null)
                    {
                        var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(DynamicAssemblyName,
                                                                                    AssemblyBuilderAccess.Run);
                        _moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");

                        IgnoresAccessChecksToAttributeGenerator.Generate(assemblyBuilder, _moduleBuilder);
                    }
                }
            }

            var typeBuilder = _moduleBuilder.DefineType(interfaceType.Name, TypeAttributes.Class | TypeAttributes.Public,
                                                        typeof(NamedBucketProvider));

            typeBuilder.AddInterfaceImplementation(interfaceType);

            var parameterTypes  = new[] { typeof(IBucketProvider), typeof(string) };
            var baseConstructor = typeof(NamedBucketProvider).GetConstructor(parameterTypes);

            var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public,
                                                                   CallingConventions.Standard | CallingConventions.HasThis, parameterTypes);

            var ilGenerator = constructorBuilder.GetILGenerator();

            ilGenerator.Emit(OpCodes.Ldarg_0); // push "this"
            ilGenerator.Emit(OpCodes.Ldarg_1); // push the I
            ilGenerator.Emit(OpCodes.Ldarg_2); // push the param
            ilGenerator.Emit(OpCodes.Call, baseConstructor !);
            ilGenerator.Emit(OpCodes.Ret);

            return(typeBuilder.CreateTypeInfo() !.AsType());
        }