diff --git a/BUILD b/BUILD
index 303f4fae2dd3a339e82a0e8a1d43f5bf30b3f79f..3874e9b6fd38b7e91972ab4659da264f9c6d5630 100644
--- a/BUILD
+++ b/BUILD
@@ -166,6 +166,7 @@ cc_library(
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/rpc_metric_id.h",
     "src/core/ext/client_config/client_channel.h",
+    "src/core/ext/client_config/client_channel_factory.h",
     "src/core/ext/client_config/client_config.h",
     "src/core/ext/client_config/connector.h",
     "src/core/ext/client_config/initial_connect_string.h",
@@ -176,7 +177,6 @@ cc_library(
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
     "src/core/ext/client_config/subchannel.h",
-    "src/core/ext/client_config/subchannel_factory.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
@@ -301,6 +301,7 @@ cc_library(
     "src/core/ext/census/tracing.c",
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/client_channel.c",
+    "src/core/ext/client_config/client_channel_factory.c",
     "src/core/ext/client_config/client_config.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
@@ -312,7 +313,6 @@ cc_library(
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
     "src/core/ext/client_config/subchannel.c",
-    "src/core/ext/client_config/subchannel_factory.c",
     "src/core/ext/client_config/subchannel_index.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
@@ -529,6 +529,7 @@ cc_library(
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/rpc_metric_id.h",
     "src/core/ext/client_config/client_channel.h",
+    "src/core/ext/client_config/client_channel_factory.h",
     "src/core/ext/client_config/client_config.h",
     "src/core/ext/client_config/connector.h",
     "src/core/ext/client_config/initial_connect_string.h",
@@ -539,7 +540,6 @@ cc_library(
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
     "src/core/ext/client_config/subchannel.h",
-    "src/core/ext/client_config/subchannel_factory.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
@@ -650,6 +650,7 @@ cc_library(
     "src/core/ext/census/tracing.c",
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/client_channel.c",
+    "src/core/ext/client_config/client_channel_factory.c",
     "src/core/ext/client_config/client_config.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
@@ -661,7 +662,6 @@ cc_library(
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
     "src/core/ext/client_config/subchannel.c",
-    "src/core/ext/client_config/subchannel_factory.c",
     "src/core/ext/client_config/subchannel_index.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
@@ -1355,6 +1355,7 @@ objc_library(
     "src/core/ext/census/tracing.c",
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/client_channel.c",
+    "src/core/ext/client_config/client_channel_factory.c",
     "src/core/ext/client_config/client_config.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
@@ -1366,7 +1367,6 @@ objc_library(
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
     "src/core/ext/client_config/subchannel.c",
-    "src/core/ext/client_config/subchannel_factory.c",
     "src/core/ext/client_config/subchannel_index.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
@@ -1525,6 +1525,7 @@ objc_library(
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/rpc_metric_id.h",
     "src/core/ext/client_config/client_channel.h",
+    "src/core/ext/client_config/client_channel_factory.h",
     "src/core/ext/client_config/client_config.h",
     "src/core/ext/client_config/connector.h",
     "src/core/ext/client_config/initial_connect_string.h",
@@ -1535,7 +1536,6 @@ objc_library(
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
     "src/core/ext/client_config/subchannel.h",
-    "src/core/ext/client_config/subchannel_factory.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
diff --git a/Makefile b/Makefile
index bad86be527266a2cd73ae12c28f6e773e85f57fc..a6b0463ab7d9bc96a76d2c5f45ae78d1866114ad 100644
--- a/Makefile
+++ b/Makefile
@@ -2449,6 +2449,7 @@ LIBGRPC_SRC = \
     src/core/ext/census/tracing.c \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/client_channel.c \
+    src/core/ext/client_config/client_channel_factory.c \
     src/core/ext/client_config/client_config.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/default_initial_connect_string.c \
@@ -2460,7 +2461,6 @@ LIBGRPC_SRC = \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_registry.c \
     src/core/ext/client_config/subchannel.c \
-    src/core/ext/client_config/subchannel_factory.c \
     src/core/ext/client_config/subchannel_index.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/lb_policy/grpclb/load_balancer_api.c \
@@ -2808,6 +2808,7 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/census/tracing.c \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/client_channel.c \
+    src/core/ext/client_config/client_channel_factory.c \
     src/core/ext/client_config/client_config.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/default_initial_connect_string.c \
@@ -2819,7 +2820,6 @@ LIBGRPC_UNSECURE_SRC = \
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_registry.c \
     src/core/ext/client_config/subchannel.c \
-    src/core/ext/client_config/subchannel_factory.c \
     src/core/ext/client_config/subchannel_index.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/lb_policy/grpclb/load_balancer_api.c \
diff --git a/binding.gyp b/binding.gyp
index 584d5d39e007675c33db68513dfa08d0a5968712..3ae14f22a452fb810dd0c76578221de86e87846e 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -569,6 +569,7 @@
         'src/core/ext/census/tracing.c',
         'src/core/ext/client_config/channel_connectivity.c',
         'src/core/ext/client_config/client_channel.c',
+        'src/core/ext/client_config/client_channel_factory.c',
         'src/core/ext/client_config/client_config.c',
         'src/core/ext/client_config/connector.c',
         'src/core/ext/client_config/default_initial_connect_string.c',
@@ -580,7 +581,6 @@
         'src/core/ext/client_config/resolver_factory.c',
         'src/core/ext/client_config/resolver_registry.c',
         'src/core/ext/client_config/subchannel.c',
-        'src/core/ext/client_config/subchannel_factory.c',
         'src/core/ext/client_config/subchannel_index.c',
         'src/core/ext/client_config/uri_parser.c',
         'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
diff --git a/build.yaml b/build.yaml
index 713afbb661959bfe12bac90e64c2a8e85c8f37ae..8ff7bb920945d2e03fb3e481f5604738bb0d2bca 100644
--- a/build.yaml
+++ b/build.yaml
@@ -415,6 +415,7 @@ filegroups:
 - name: grpc_client_config
   headers:
   - src/core/ext/client_config/client_channel.h
+  - src/core/ext/client_config/client_channel_factory.h
   - src/core/ext/client_config/client_config.h
   - src/core/ext/client_config/connector.h
   - src/core/ext/client_config/initial_connect_string.h
@@ -425,12 +426,12 @@ filegroups:
   - src/core/ext/client_config/resolver_factory.h
   - src/core/ext/client_config/resolver_registry.h
   - src/core/ext/client_config/subchannel.h
-  - src/core/ext/client_config/subchannel_factory.h
   - src/core/ext/client_config/subchannel_index.h
   - src/core/ext/client_config/uri_parser.h
   src:
   - src/core/ext/client_config/channel_connectivity.c
   - src/core/ext/client_config/client_channel.c
+  - src/core/ext/client_config/client_channel_factory.c
   - src/core/ext/client_config/client_config.c
   - src/core/ext/client_config/connector.c
   - src/core/ext/client_config/default_initial_connect_string.c
@@ -442,7 +443,6 @@ filegroups:
   - src/core/ext/client_config/resolver_factory.c
   - src/core/ext/client_config/resolver_registry.c
   - src/core/ext/client_config/subchannel.c
-  - src/core/ext/client_config/subchannel_factory.c
   - src/core/ext/client_config/subchannel_index.c
   - src/core/ext/client_config/uri_parser.c
 - name: grpc_codegen
diff --git a/config.m4 b/config.m4
index 8239a3b20245023508b463cc632f68ac7bb98f24..1acc64e9e9be1a2e62083565092a46fb60b73ad8 100644
--- a/config.m4
+++ b/config.m4
@@ -91,6 +91,7 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/census/tracing.c \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/client_channel.c \
+    src/core/ext/client_config/client_channel_factory.c \
     src/core/ext/client_config/client_config.c \
     src/core/ext/client_config/connector.c \
     src/core/ext/client_config/default_initial_connect_string.c \
@@ -102,7 +103,6 @@ if test "$PHP_GRPC" != "no"; then
     src/core/ext/client_config/resolver_factory.c \
     src/core/ext/client_config/resolver_registry.c \
     src/core/ext/client_config/subchannel.c \
-    src/core/ext/client_config/subchannel_factory.c \
     src/core/ext/client_config/subchannel_index.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/lb_policy/grpclb/load_balancer_api.c \
diff --git a/gRPC.podspec b/gRPC.podspec
index 3845539c5ddc9a9ef91448a59ff9dfffce4db97e..bf4ce966e6bf5a9e72eab6577715ed8d4858ebc5 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -168,6 +168,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/census/mlog.h',
                       'src/core/ext/census/rpc_metric_id.h',
                       'src/core/ext/client_config/client_channel.h',
+                      'src/core/ext/client_config/client_channel_factory.h',
                       'src/core/ext/client_config/client_config.h',
                       'src/core/ext/client_config/connector.h',
                       'src/core/ext/client_config/initial_connect_string.h',
@@ -178,7 +179,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_config/resolver_factory.h',
                       'src/core/ext/client_config/resolver_registry.h',
                       'src/core/ext/client_config/subchannel.h',
-                      'src/core/ext/client_config/subchannel_factory.h',
                       'src/core/ext/client_config/subchannel_index.h',
                       'src/core/ext/client_config/uri_parser.h',
                       'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
@@ -320,6 +320,7 @@ Pod::Spec.new do |s|
                       'src/core/ext/census/tracing.c',
                       'src/core/ext/client_config/channel_connectivity.c',
                       'src/core/ext/client_config/client_channel.c',
+                      'src/core/ext/client_config/client_channel_factory.c',
                       'src/core/ext/client_config/client_config.c',
                       'src/core/ext/client_config/connector.c',
                       'src/core/ext/client_config/default_initial_connect_string.c',
@@ -331,7 +332,6 @@ Pod::Spec.new do |s|
                       'src/core/ext/client_config/resolver_factory.c',
                       'src/core/ext/client_config/resolver_registry.c',
                       'src/core/ext/client_config/subchannel.c',
-                      'src/core/ext/client_config/subchannel_factory.c',
                       'src/core/ext/client_config/subchannel_index.c',
                       'src/core/ext/client_config/uri_parser.c',
                       'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
@@ -491,6 +491,7 @@ Pod::Spec.new do |s|
                               'src/core/ext/census/mlog.h',
                               'src/core/ext/census/rpc_metric_id.h',
                               'src/core/ext/client_config/client_channel.h',
+                              'src/core/ext/client_config/client_channel_factory.h',
                               'src/core/ext/client_config/client_config.h',
                               'src/core/ext/client_config/connector.h',
                               'src/core/ext/client_config/initial_connect_string.h',
@@ -501,7 +502,6 @@ Pod::Spec.new do |s|
                               'src/core/ext/client_config/resolver_factory.h',
                               'src/core/ext/client_config/resolver_registry.h',
                               'src/core/ext/client_config/subchannel.h',
-                              'src/core/ext/client_config/subchannel_factory.h',
                               'src/core/ext/client_config/subchannel_index.h',
                               'src/core/ext/client_config/uri_parser.h',
                               'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 8538f2b9801e8643fd11f4f59aa3587131d79b2a..b491af9116354cf8f03d1b0924fe25253e0c5dd3 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -164,6 +164,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/census/mlog.h )
   s.files += %w( src/core/ext/census/rpc_metric_id.h )
   s.files += %w( src/core/ext/client_config/client_channel.h )
+  s.files += %w( src/core/ext/client_config/client_channel_factory.h )
   s.files += %w( src/core/ext/client_config/client_config.h )
   s.files += %w( src/core/ext/client_config/connector.h )
   s.files += %w( src/core/ext/client_config/initial_connect_string.h )
@@ -174,7 +175,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_config/resolver_factory.h )
   s.files += %w( src/core/ext/client_config/resolver_registry.h )
   s.files += %w( src/core/ext/client_config/subchannel.h )
-  s.files += %w( src/core/ext/client_config/subchannel_factory.h )
   s.files += %w( src/core/ext/client_config/subchannel_index.h )
   s.files += %w( src/core/ext/client_config/uri_parser.h )
   s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.h )
@@ -303,6 +303,7 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/census/tracing.c )
   s.files += %w( src/core/ext/client_config/channel_connectivity.c )
   s.files += %w( src/core/ext/client_config/client_channel.c )
+  s.files += %w( src/core/ext/client_config/client_channel_factory.c )
   s.files += %w( src/core/ext/client_config/client_config.c )
   s.files += %w( src/core/ext/client_config/connector.c )
   s.files += %w( src/core/ext/client_config/default_initial_connect_string.c )
@@ -314,7 +315,6 @@ Gem::Specification.new do |s|
   s.files += %w( src/core/ext/client_config/resolver_factory.c )
   s.files += %w( src/core/ext/client_config/resolver_registry.c )
   s.files += %w( src/core/ext/client_config/subchannel.c )
-  s.files += %w( src/core/ext/client_config/subchannel_factory.c )
   s.files += %w( src/core/ext/client_config/subchannel_index.c )
   s.files += %w( src/core/ext/client_config/uri_parser.c )
   s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.c )
diff --git a/package.json b/package.json
index 2ebb73130090ed0c3ee19a37670cff610c79dfc5..1ce1ac07282342bd83d872ff645396ec81b1b046 100644
--- a/package.json
+++ b/package.json
@@ -107,6 +107,7 @@
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/rpc_metric_id.h",
     "src/core/ext/client_config/client_channel.h",
+    "src/core/ext/client_config/client_channel_factory.h",
     "src/core/ext/client_config/client_config.h",
     "src/core/ext/client_config/connector.h",
     "src/core/ext/client_config/initial_connect_string.h",
@@ -117,7 +118,6 @@
     "src/core/ext/client_config/resolver_factory.h",
     "src/core/ext/client_config/resolver_registry.h",
     "src/core/ext/client_config/subchannel.h",
-    "src/core/ext/client_config/subchannel_factory.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
@@ -246,6 +246,7 @@
     "src/core/ext/census/tracing.c",
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/client_channel.c",
+    "src/core/ext/client_config/client_channel_factory.c",
     "src/core/ext/client_config/client_config.c",
     "src/core/ext/client_config/connector.c",
     "src/core/ext/client_config/default_initial_connect_string.c",
@@ -257,7 +258,6 @@
     "src/core/ext/client_config/resolver_factory.c",
     "src/core/ext/client_config/resolver_registry.c",
     "src/core/ext/client_config/subchannel.c",
-    "src/core/ext/client_config/subchannel_factory.c",
     "src/core/ext/client_config/subchannel_index.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
diff --git a/package.xml b/package.xml
index 130b7ff8978fa30249578b4a465f2477f787475f..bf27fcd3995d761ca687eb5ad98a892314e46f80 100644
--- a/package.xml
+++ b/package.xml
@@ -168,6 +168,7 @@
     <file baseinstalldir="/" name="src/core/ext/census/mlog.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/rpc_metric_id.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_channel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/client_config/client_channel_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_config.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/connector.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/initial_connect_string.h" role="src" />
@@ -178,7 +179,6 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_registry.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel.h" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_factory.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_index.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/uri_parser.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.h" role="src" />
@@ -307,6 +307,7 @@
     <file baseinstalldir="/" name="src/core/ext/census/tracing.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/channel_connectivity.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_channel.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/client_config/client_channel_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/client_config.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/connector.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/default_initial_connect_string.c" role="src" />
@@ -318,7 +319,6 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/resolver_registry.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_factory.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_index.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/uri_parser.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.c" role="src" />
diff --git a/src/core/ext/client_config/README.md b/src/core/ext/client_config/README.md
index fff7a5af5b65e9fbfd7288192fca84aaeacc2497..7024fd540d867b030e027ecb6174bd0a655add93 100644
--- a/src/core/ext/client_config/README.md
+++ b/src/core/ext/client_config/README.md
@@ -40,7 +40,7 @@ decisions (for example, by avoiding disconnected backends).
 Configured sub-channels are fully setup to participate in the grpc data plane.
 Their behavior is specified by a set of grpc channel filters defined at their
 construction. To customize this behavior, resolvers build
-grpc_subchannel_factory objects, which use the decorator pattern to customize
+grpc_client_channel_factory objects, which use the decorator pattern to customize
 construction arguments for concrete grpc_subchannel instances.
 
 
diff --git a/src/core/ext/client_config/client_channel_factory.c b/src/core/ext/client_config/client_channel_factory.c
new file mode 100644
index 0000000000000000000000000000000000000000..71c64c0da1b4ab20b9342646f2cb4cc4ac49db65
--- /dev/null
+++ b/src/core/ext/client_config/client_channel_factory.c
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/ext/client_config/client_channel_factory.h"
+
+void grpc_client_channel_factory_ref(grpc_client_channel_factory* factory) {
+  factory->vtable->ref(factory);
+}
+
+void grpc_client_channel_factory_unref(grpc_exec_ctx* exec_ctx,
+                                       grpc_client_channel_factory* factory) {
+  factory->vtable->unref(exec_ctx, factory);
+}
+
+grpc_subchannel* grpc_client_channel_factory_create_subchannel(
+    grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory,
+    grpc_subchannel_args* args) {
+  return factory->vtable->create_subchannel(exec_ctx, factory, args);
+}
+
+grpc_channel* grpc_client_channel_factory_create_channel(
+    grpc_exec_ctx* exec_ctx, grpc_client_channel_factory* factory,
+    const char* target, grpc_client_channel_type type,
+    grpc_channel_args* args) {
+  return factory->vtable->create_client_channel(exec_ctx, factory, target, type,
+                                                args);
+}
diff --git a/src/core/ext/client_config/client_channel_factory.h b/src/core/ext/client_config/client_channel_factory.h
new file mode 100644
index 0000000000000000000000000000000000000000..42a3034c78ff665c8e70ee27f1aeeea49623900b
--- /dev/null
+++ b/src/core/ext/client_config/client_channel_factory.h
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CHANNEL_FACTORY_H
+#define GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CHANNEL_FACTORY_H
+
+#include <grpc/grpc_security.h>
+#include <grpc/impl/codegen/grpc_types.h>
+
+#include "src/core/ext/client_config/subchannel.h"
+#include "src/core/lib/channel/channel_stack.h"
+
+typedef struct grpc_client_channel_factory grpc_client_channel_factory;
+typedef struct grpc_client_channel_factory_vtable
+    grpc_client_channel_factory_vtable;
+
+typedef enum {
+  GRPC_CLIENT_CHANNEL_TYPE_REGULAR, /** for the user-level regular calls */
+  GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, /** for communication with a load
+                                              balancing service */
+} grpc_client_channel_type;
+
+/** Constructor for new configured channels.
+    Creating decorators around this type is encouraged to adapt behavior. */
+struct grpc_client_channel_factory {
+  const grpc_client_channel_factory_vtable *vtable;
+};
+
+struct grpc_client_channel_factory_vtable {
+  void (*ref)(grpc_client_channel_factory *factory);
+  void (*unref)(grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory);
+  grpc_subchannel *(*create_subchannel)(grpc_exec_ctx *exec_ctx,
+                                        grpc_client_channel_factory *factory,
+                                        grpc_subchannel_args *args);
+  grpc_channel *(*create_client_channel)(grpc_exec_ctx *exec_ctx,
+                                         grpc_client_channel_factory *factory,
+                                         const char *target,
+                                         grpc_client_channel_type type,
+                                         grpc_channel_args *args);
+};
+
+void grpc_client_channel_factory_ref(grpc_client_channel_factory *factory);
+void grpc_client_channel_factory_unref(grpc_exec_ctx *exec_ctx,
+                                       grpc_client_channel_factory *factory);
+
+/** Create a new grpc_subchannel */
+grpc_subchannel *grpc_client_channel_factory_create_subchannel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory,
+    grpc_subchannel_args *args);
+
+/** Create a new grpc_channel */
+grpc_channel *grpc_client_channel_factory_create_channel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory,
+    const char *target, grpc_client_channel_type type, grpc_channel_args *args);
+
+#endif /* GRPC_CORE_LIB_CLIENT_CONFIG_CLIENT_CHANNEL_FACTORY_H */
diff --git a/src/core/ext/client_config/lb_policy_factory.h b/src/core/ext/client_config/lb_policy_factory.h
index 4a0a267ea31ac1413f3af46fb7c9b2c46c265d1c..1c89b28b59a3301dbfad3c26a3e5db67341b8005 100644
--- a/src/core/ext/client_config/lb_policy_factory.h
+++ b/src/core/ext/client_config/lb_policy_factory.h
@@ -34,8 +34,8 @@
 #ifndef GRPC_CORE_EXT_CLIENT_CONFIG_LB_POLICY_FACTORY_H
 #define GRPC_CORE_EXT_CLIENT_CONFIG_LB_POLICY_FACTORY_H
 
+#include "src/core/ext/client_config/client_channel_factory.h"
 #include "src/core/ext/client_config/lb_policy.h"
-#include "src/core/ext/client_config/subchannel_factory.h"
 #include "src/core/lib/iomgr/resolve_address.h"
 
 #include "src/core/lib/iomgr/exec_ctx.h"
@@ -51,7 +51,7 @@ struct grpc_lb_policy_factory {
 
 typedef struct grpc_lb_policy_args {
   grpc_resolved_addresses *addresses;
-  grpc_subchannel_factory *subchannel_factory;
+  grpc_client_channel_factory *client_channel_factory;
 } grpc_lb_policy_args;
 
 struct grpc_lb_policy_factory_vtable {
diff --git a/src/core/ext/client_config/resolver_factory.h b/src/core/ext/client_config/resolver_factory.h
index 1a3519092d35a39d1c81ecf133068722fd9b4dd4..4eb6979aad8d9e2bdabd392f77dc1e566fd5d7c0 100644
--- a/src/core/ext/client_config/resolver_factory.h
+++ b/src/core/ext/client_config/resolver_factory.h
@@ -34,8 +34,8 @@
 #ifndef GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_FACTORY_H
 #define GRPC_CORE_EXT_CLIENT_CONFIG_RESOLVER_FACTORY_H
 
+#include "src/core/ext/client_config/client_channel_factory.h"
 #include "src/core/ext/client_config/resolver.h"
-#include "src/core/ext/client_config/subchannel_factory.h"
 #include "src/core/ext/client_config/uri_parser.h"
 
 typedef struct grpc_resolver_factory grpc_resolver_factory;
@@ -49,7 +49,7 @@ struct grpc_resolver_factory {
 
 typedef struct grpc_resolver_args {
   grpc_uri *uri;
-  grpc_subchannel_factory *subchannel_factory;
+  grpc_client_channel_factory *client_channel_factory;
 } grpc_resolver_args;
 
 struct grpc_resolver_factory_vtable {
diff --git a/src/core/ext/client_config/resolver_registry.c b/src/core/ext/client_config/resolver_registry.c
index 63609e823415c1c665775d348df4819fc2d1d51b..07f29bcb27a9b1de6fdbd76243fa7446889c31f0 100644
--- a/src/core/ext/client_config/resolver_registry.c
+++ b/src/core/ext/client_config/resolver_registry.c
@@ -123,14 +123,14 @@ static grpc_resolver_factory *resolve_factory(const char *target,
 }
 
 grpc_resolver *grpc_resolver_create(
-    const char *target, grpc_subchannel_factory *subchannel_factory) {
+    const char *target, grpc_client_channel_factory *client_channel_factory) {
   grpc_uri *uri = NULL;
   grpc_resolver_factory *factory = resolve_factory(target, &uri);
   grpc_resolver *resolver;
   grpc_resolver_args args;
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  args.subchannel_factory = subchannel_factory;
+  args.client_channel_factory = client_channel_factory;
   resolver = grpc_resolver_factory_create_resolver(factory, &args);
   grpc_uri_destroy(uri);
   return resolver;
diff --git a/src/core/ext/client_config/resolver_registry.h b/src/core/ext/client_config/resolver_registry.h
index 0467671d38573f2e66d28bf3f96b180784d1d2c4..5ef1383cd35d607b00d3f62ca6f450cfeaf020a3 100644
--- a/src/core/ext/client_config/resolver_registry.h
+++ b/src/core/ext/client_config/resolver_registry.h
@@ -56,7 +56,7 @@ void grpc_register_resolver_type(grpc_resolver_factory *factory);
     return it.
     If a resolver factory was not found, return NULL. */
 grpc_resolver *grpc_resolver_create(
-    const char *target, grpc_subchannel_factory *subchannel_factory);
+    const char *target, grpc_client_channel_factory *client_channel_factory);
 
 /** Find a resolver factory given a name and return an (owned-by-the-caller)
  *  reference to it */
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c
index 9afa219aaa9919cb868505ef9dd61d4d06e0b199..cac62b81ea593e6ea2393831cea8512fe9fb3ecc 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -395,7 +395,7 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
                                          grpc_lb_policy_factory *factory,
                                          grpc_lb_policy_args *args) {
   GPR_ASSERT(args->addresses != NULL);
-  GPR_ASSERT(args->subchannel_factory != NULL);
+  GPR_ASSERT(args->client_channel_factory != NULL);
 
   if (args->addresses->naddrs == 0) return NULL;
 
@@ -412,8 +412,8 @@ static grpc_lb_policy *create_pick_first(grpc_exec_ctx *exec_ctx,
     sc_args.addr = (struct sockaddr *)(args->addresses->addrs[i].addr);
     sc_args.addr_len = (size_t)args->addresses->addrs[i].len;
 
-    grpc_subchannel *subchannel = grpc_subchannel_factory_create_subchannel(
-        exec_ctx, args->subchannel_factory, &sc_args);
+    grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
+        exec_ctx, args->client_channel_factory, &sc_args);
 
     if (subchannel != NULL) {
       p->subchannels[subchannel_idx++] = subchannel;
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index eb168a6215c04062e40e1913e774ba0c6d7ea09f..16f3942d3a3374a3a163a898170add558ef671dd 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -502,7 +502,7 @@ static grpc_lb_policy *create_round_robin(grpc_exec_ctx *exec_ctx,
                                           grpc_lb_policy_factory *factory,
                                           grpc_lb_policy_args *args) {
   GPR_ASSERT(args->addresses != NULL);
-  GPR_ASSERT(args->subchannel_factory != NULL);
+  GPR_ASSERT(args->client_channel_factory != NULL);
 
   round_robin_lb_policy *p = gpr_malloc(sizeof(*p));
   memset(p, 0, sizeof(*p));
@@ -518,8 +518,8 @@ static grpc_lb_policy *create_round_robin(grpc_exec_ctx *exec_ctx,
     sc_args.addr = (struct sockaddr *)(args->addresses->addrs[i].addr);
     sc_args.addr_len = (size_t)args->addresses->addrs[i].len;
 
-    grpc_subchannel *subchannel = grpc_subchannel_factory_create_subchannel(
-        exec_ctx, args->subchannel_factory, &sc_args);
+    grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
+        exec_ctx, args->client_channel_factory, &sc_args);
 
     if (subchannel != NULL) {
       subchannel_data *sd = gpr_malloc(sizeof(*sd));
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 95126ab2032529b7c95f7ddb9685b3e353d50a23..2749b0ca01034de42496831b96d2ea4490bde332 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -59,7 +59,7 @@ typedef struct {
   /** default port to use */
   char *default_port;
   /** subchannel factory */
-  grpc_subchannel_factory *subchannel_factory;
+  grpc_client_channel_factory *client_channel_factory;
   /** load balancing policy name */
   char *lb_policy_name;
 
@@ -170,7 +170,7 @@ static void dns_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
     config = grpc_client_config_create();
     memset(&lb_policy_args, 0, sizeof(lb_policy_args));
     lb_policy_args.addresses = addresses;
-    lb_policy_args.subchannel_factory = r->subchannel_factory;
+    lb_policy_args.client_channel_factory = r->client_channel_factory;
     lb_policy =
         grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
     if (lb_policy != NULL) {
@@ -228,7 +228,7 @@ static void dns_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
   if (r->resolved_config) {
     grpc_client_config_unref(exec_ctx, r->resolved_config);
   }
-  grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory);
+  grpc_client_channel_factory_unref(exec_ctx, r->client_channel_factory);
   gpr_free(r->name);
   gpr_free(r->default_port);
   gpr_free(r->lb_policy_name);
@@ -255,10 +255,10 @@ static grpc_resolver *dns_create(grpc_resolver_args *args,
   grpc_resolver_init(&r->base, &dns_resolver_vtable);
   r->name = gpr_strdup(path);
   r->default_port = gpr_strdup(default_port);
-  r->subchannel_factory = args->subchannel_factory;
+  r->client_channel_factory = args->client_channel_factory;
   gpr_backoff_init(&r->backoff_state, BACKOFF_MULTIPLIER, BACKOFF_JITTER,
                    BACKOFF_MIN_SECONDS * 1000, BACKOFF_MAX_SECONDS * 1000);
-  grpc_subchannel_factory_ref(r->subchannel_factory);
+  grpc_client_channel_factory_ref(r->client_channel_factory);
   r->lb_policy_name = gpr_strdup(lb_policy_name);
   return &r->base;
 }
diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
index 3c97e659bff7e83419c57c014e72a98078fb8d0e..6733c4e2fd486f14ddd63ff296bab93481407e23 100644
--- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
@@ -52,7 +52,7 @@ typedef struct {
   /** refcount */
   gpr_refcount refs;
   /** subchannel factory */
-  grpc_subchannel_factory *subchannel_factory;
+  grpc_client_channel_factory *client_channel_factory;
   /** load balancing policy name */
   char *lb_policy_name;
 
@@ -125,7 +125,7 @@ static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
     grpc_lb_policy_args lb_policy_args;
     memset(&lb_policy_args, 0, sizeof(lb_policy_args));
     lb_policy_args.addresses = r->addresses;
-    lb_policy_args.subchannel_factory = r->subchannel_factory;
+    lb_policy_args.client_channel_factory = r->client_channel_factory;
     grpc_lb_policy *lb_policy =
         grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
     grpc_client_config_set_lb_policy(cfg, lb_policy);
@@ -140,7 +140,7 @@ static void sockaddr_maybe_finish_next_locked(grpc_exec_ctx *exec_ctx,
 static void sockaddr_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
   sockaddr_resolver *r = (sockaddr_resolver *)gr;
   gpr_mu_destroy(&r->mu);
-  grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory);
+  grpc_client_channel_factory_unref(exec_ctx, r->client_channel_factory);
   grpc_resolved_addresses_destroy(r->addresses);
   gpr_free(r->lb_policy_name);
   gpr_free(r);
@@ -318,8 +318,8 @@ static grpc_resolver *sockaddr_create(
   gpr_ref_init(&r->refs, 1);
   gpr_mu_init(&r->mu);
   grpc_resolver_init(&r->base, &sockaddr_resolver_vtable);
-  r->subchannel_factory = args->subchannel_factory;
-  grpc_subchannel_factory_ref(r->subchannel_factory);
+  r->client_channel_factory = args->client_channel_factory;
+  grpc_client_channel_factory_ref(r->client_channel_factory);
 
   return &r->base;
 }
diff --git a/src/core/ext/resolver/zookeeper/zookeeper_resolver.c b/src/core/ext/resolver/zookeeper/zookeeper_resolver.c
index cd065bef0978d85fec526db79336cf09c8c5e5d1..898632c3cd4369ec7136fc9139094dc399ce4c83 100644
--- a/src/core/ext/resolver/zookeeper/zookeeper_resolver.c
+++ b/src/core/ext/resolver/zookeeper/zookeeper_resolver.c
@@ -57,7 +57,7 @@ typedef struct {
   /** name to resolve */
   char *name;
   /** subchannel factory */
-  grpc_subchannel_factory *subchannel_factory;
+  grpc_client_channel_factory *client_channel_factory;
   /** load balancing policy name */
   char *lb_policy_name;
 
@@ -187,9 +187,8 @@ static void zookeeper_on_resolved(grpc_exec_ctx *exec_ctx, void *arg,
   if (addresses != NULL) {
     grpc_lb_policy_args lb_policy_args;
     config = grpc_client_config_create();
-
     lb_policy_args.addresses = addresses;
-    lb_policy_args.subchannel_factory = r->subchannel_factory;
+    lb_policy_args.client_channel_factory = r->client_channel_factory;
     lb_policy =
         grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
 
@@ -424,7 +423,7 @@ static void zookeeper_destroy(grpc_exec_ctx *exec_ctx, grpc_resolver *gr) {
   if (r->resolved_config != NULL) {
     grpc_client_config_unref(exec_ctx, r->resolved_config);
   }
-  grpc_subchannel_factory_unref(exec_ctx, r->subchannel_factory);
+  grpc_client_channel_factory_unref(exec_ctx, r->client_channel_factory);
   gpr_free(r->name);
   gpr_free(r->lb_policy_name);
   gpr_free(r);
@@ -454,8 +453,8 @@ static grpc_resolver *zookeeper_create(grpc_resolver_args *args,
   grpc_resolver_init(&r->base, &zookeeper_resolver_vtable);
   r->name = gpr_strdup(path);
 
-  r->subchannel_factory = args->subchannel_factory;
-  grpc_subchannel_factory_ref(r->subchannel_factory);
+  r->client_channel_factory = args->client_channel_factory;
+  grpc_client_channel_factory_ref(r->client_channel_factory);
 
   r->lb_policy_name = gpr_strdup(lb_policy_name);
 
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create.c b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
index 5ebeed4373d1a10305523458f9a5d73f58c5dc63..5484438f0a082f3898ccfd1e737ef63c8940f76c 100644
--- a/src/core/ext/transport/chttp2/client/insecure/channel_create.c
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create.c
@@ -136,31 +136,35 @@ static const grpc_connector_vtable connector_vtable = {
     connector_ref, connector_unref, connector_shutdown, connector_connect};
 
 typedef struct {
-  grpc_subchannel_factory base;
+  grpc_client_channel_factory base;
   gpr_refcount refs;
   grpc_channel_args *merge_args;
   grpc_channel *master;
-} subchannel_factory;
+} client_channel_factory;
 
-static void subchannel_factory_ref(grpc_subchannel_factory *scf) {
-  subchannel_factory *f = (subchannel_factory *)scf;
+static void client_channel_factory_ref(
+    grpc_client_channel_factory *cc_factory) {
+  client_channel_factory *f = (client_channel_factory *)cc_factory;
   gpr_ref(&f->refs);
 }
 
-static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
-                                     grpc_subchannel_factory *scf) {
-  subchannel_factory *f = (subchannel_factory *)scf;
+static void client_channel_factory_unref(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
+  client_channel_factory *f = (client_channel_factory *)cc_factory;
   if (gpr_unref(&f->refs)) {
-    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
+    if (f->master != NULL) {
+      GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master,
+                                  "client_channel_factory");
+    }
     grpc_channel_args_destroy(f->merge_args);
     gpr_free(f);
   }
 }
 
-static grpc_subchannel *subchannel_factory_create_subchannel(
-    grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf,
+static grpc_subchannel *client_channel_factory_create_subchannel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
     grpc_subchannel_args *args) {
-  subchannel_factory *f = (subchannel_factory *)scf;
+  client_channel_factory *f = (client_channel_factory *)cc_factory;
   connector *c = gpr_malloc(sizeof(*c));
   grpc_channel_args *final_args =
       grpc_channel_args_merge(args->args, f->merge_args);
@@ -175,9 +179,33 @@ static grpc_subchannel *subchannel_factory_create_subchannel(
   return s;
 }
 
-static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {
-    subchannel_factory_ref, subchannel_factory_unref,
-    subchannel_factory_create_subchannel};
+static grpc_channel *client_channel_factory_create_channel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
+    const char *target, grpc_client_channel_type type,
+    grpc_channel_args *args) {
+  client_channel_factory *f = (client_channel_factory *)cc_factory;
+  grpc_channel_args *final_args = grpc_channel_args_merge(args, f->merge_args);
+  grpc_channel *channel = grpc_channel_create(exec_ctx, target, final_args,
+                                              GRPC_CLIENT_CHANNEL, NULL);
+  grpc_channel_args_destroy(final_args);
+  grpc_resolver *resolver = grpc_resolver_create(target, &f->base);
+  if (!resolver) {
+    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
+                                "client_channel_factory_create_channel");
+    return NULL;
+  }
+
+  grpc_client_channel_set_resolver(
+      exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
+  GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create_channel");
+
+  return channel;
+}
+
+static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
+    {client_channel_factory_ref, client_channel_factory_unref,
+     client_channel_factory_create_subchannel,
+     client_channel_factory_create_channel};
 
 /* Create a client channel:
    Asynchronously: - resolve target
@@ -186,38 +214,27 @@ static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {
 grpc_channel *grpc_insecure_channel_create(const char *target,
                                            const grpc_channel_args *args,
                                            void *reserved) {
-  grpc_channel *channel = NULL;
-  grpc_resolver *resolver;
-  subchannel_factory *f;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   GRPC_API_TRACE(
       "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
       (target, args, reserved));
   GPR_ASSERT(!reserved);
 
-  channel =
-      grpc_channel_create(&exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
-
-  f = gpr_malloc(sizeof(*f));
-  f->base.vtable = &subchannel_factory_vtable;
+  client_channel_factory *f = gpr_malloc(sizeof(*f));
+  memset(f, 0, sizeof(*f));
+  f->base.vtable = &client_channel_factory_vtable;
   gpr_ref_init(&f->refs, 1);
   f->merge_args = grpc_channel_args_copy(args);
-  f->master = channel;
-  GRPC_CHANNEL_INTERNAL_REF(f->master, "subchannel_factory");
-  resolver = grpc_resolver_create(target, &f->base);
-  if (!resolver) {
-    GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, f->master, "subchannel_factory");
-    grpc_subchannel_factory_unref(&exec_ctx, &f->base);
-    grpc_exec_ctx_finish(&exec_ctx);
-    return NULL;
-  }
 
-  grpc_client_channel_set_resolver(
-      &exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
-  GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create");
-  grpc_subchannel_factory_unref(&exec_ctx, &f->base);
+  grpc_channel *channel = client_channel_factory_create_channel(
+      &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, NULL);
+  if (channel != NULL) {
+    f->master = channel;
+    GRPC_CHANNEL_INTERNAL_REF(f->master, "grpc_insecure_channel_create");
+  }
+  grpc_client_channel_factory_unref(&exec_ctx, &f->base);
 
   grpc_exec_ctx_finish(&exec_ctx);
 
-  return channel;
+  return channel; /* may be NULL */
 }
diff --git a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
index 702b98d961f9b59ccd6d95547acd14faa4e59c55..58af6f995a4dc1da5465299e03790674f3c3ebf2 100644
--- a/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
+++ b/src/core/ext/transport/chttp2/client/secure/secure_channel_create.c
@@ -192,34 +192,38 @@ static const grpc_connector_vtable connector_vtable = {
     connector_ref, connector_unref, connector_shutdown, connector_connect};
 
 typedef struct {
-  grpc_subchannel_factory base;
+  grpc_client_channel_factory base;
   gpr_refcount refs;
   grpc_channel_args *merge_args;
   grpc_channel_security_connector *security_connector;
   grpc_channel *master;
-} subchannel_factory;
+} client_channel_factory;
 
-static void subchannel_factory_ref(grpc_subchannel_factory *scf) {
-  subchannel_factory *f = (subchannel_factory *)scf;
+static void client_channel_factory_ref(
+    grpc_client_channel_factory *cc_factory) {
+  client_channel_factory *f = (client_channel_factory *)cc_factory;
   gpr_ref(&f->refs);
 }
 
-static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
-                                     grpc_subchannel_factory *scf) {
-  subchannel_factory *f = (subchannel_factory *)scf;
+static void client_channel_factory_unref(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory) {
+  client_channel_factory *f = (client_channel_factory *)cc_factory;
   if (gpr_unref(&f->refs)) {
     GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
-                                  "subchannel_factory");
-    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master, "subchannel_factory");
+                                  "client_channel_factory");
+    if (f->master != NULL) {
+      GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, f->master,
+                                  "client_channel_factory");
+    }
     grpc_channel_args_destroy(f->merge_args);
     gpr_free(f);
   }
 }
 
-static grpc_subchannel *subchannel_factory_create_subchannel(
-    grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *scf,
+static grpc_subchannel *client_channel_factory_create_subchannel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
     grpc_subchannel_args *args) {
-  subchannel_factory *f = (subchannel_factory *)scf;
+  client_channel_factory *f = (client_channel_factory *)cc_factory;
   connector *c = gpr_malloc(sizeof(*c));
   grpc_channel_args *final_args =
       grpc_channel_args_merge(args->args, f->merge_args);
@@ -236,9 +240,37 @@ static grpc_subchannel *subchannel_factory_create_subchannel(
   return s;
 }
 
-static const grpc_subchannel_factory_vtable subchannel_factory_vtable = {
-    subchannel_factory_ref, subchannel_factory_unref,
-    subchannel_factory_create_subchannel};
+static grpc_channel *client_channel_factory_create_channel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
+    const char *target, grpc_client_channel_type type,
+    grpc_channel_args *args) {
+  client_channel_factory *f = (client_channel_factory *)cc_factory;
+
+  grpc_channel_args *final_args = grpc_channel_args_merge(args, f->merge_args);
+  grpc_channel *channel = grpc_channel_create(exec_ctx, target, final_args,
+                                              GRPC_CLIENT_CHANNEL, NULL);
+  grpc_channel_args_destroy(final_args);
+
+  grpc_resolver *resolver = grpc_resolver_create(target, &f->base);
+  if (resolver != NULL) {
+    grpc_client_channel_set_resolver(
+        exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
+    GRPC_RESOLVER_UNREF(exec_ctx, resolver, "create");
+  } else {
+    GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel,
+                                "client_channel_factory_create_channel");
+    channel = NULL;
+  }
+
+  GRPC_SECURITY_CONNECTOR_UNREF(&f->security_connector->base,
+                                "client_channel_factory_create_channel");
+  return channel;
+}
+
+static const grpc_client_channel_factory_vtable client_channel_factory_vtable =
+    {client_channel_factory_ref, client_channel_factory_unref,
+     client_channel_factory_create_subchannel,
+     client_channel_factory_create_channel};
 
 /* Create a secure client channel:
    Asynchronously: - resolve target
@@ -248,13 +280,11 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
                                          const char *target,
                                          const grpc_channel_args *args,
                                          void *reserved) {
-  grpc_channel *channel;
   grpc_arg connector_arg;
   grpc_channel_args *args_copy;
   grpc_channel_args *new_args_from_connector;
   grpc_channel_security_connector *security_connector;
-  grpc_resolver *resolver;
-  subchannel_factory *f;
+  client_channel_factory *f;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
   GRPC_API_TRACE(
@@ -284,35 +314,30 @@ grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
       new_args_from_connector != NULL ? new_args_from_connector : args,
       &connector_arg, 1);
 
-  channel = grpc_channel_create(&exec_ctx, target, args_copy,
-                                GRPC_CLIENT_CHANNEL, NULL);
-
   f = gpr_malloc(sizeof(*f));
-  f->base.vtable = &subchannel_factory_vtable;
+  memset(f, 0, sizeof(*f));
+  f->base.vtable = &client_channel_factory_vtable;
   gpr_ref_init(&f->refs, 1);
-  GRPC_SECURITY_CONNECTOR_REF(&security_connector->base, "subchannel_factory");
-  f->security_connector = security_connector;
+
   f->merge_args = grpc_channel_args_copy(args_copy);
-  f->master = channel;
-  GRPC_CHANNEL_INTERNAL_REF(channel, "subchannel_factory");
-  resolver = grpc_resolver_create(target, &f->base);
-  if (resolver) {
-    grpc_client_channel_set_resolver(
-        &exec_ctx, grpc_channel_get_channel_stack(channel), resolver);
-    GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "create");
-  }
-  grpc_subchannel_factory_unref(&exec_ctx, &f->base);
-  GRPC_SECURITY_CONNECTOR_UNREF(&security_connector->base, "channel_create");
   grpc_channel_args_destroy(args_copy);
   if (new_args_from_connector != NULL) {
     grpc_channel_args_destroy(new_args_from_connector);
   }
 
-  if (!resolver) {
-    GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, channel, "subchannel_factory");
-    channel = NULL;
+  GRPC_SECURITY_CONNECTOR_REF(&security_connector->base,
+                              "grpc_secure_channel_create");
+  f->security_connector = security_connector;
+
+  grpc_channel *channel = client_channel_factory_create_channel(
+      &exec_ctx, &f->base, target, GRPC_CLIENT_CHANNEL_TYPE_REGULAR, NULL);
+  if (channel != NULL) {
+    f->master = channel;
+    GRPC_CHANNEL_INTERNAL_REF(f->master, "grpc_secure_channel_create");
   }
+
+  grpc_client_channel_factory_unref(&exec_ctx, &f->base);
   grpc_exec_ctx_finish(&exec_ctx);
 
-  return channel;
+  return channel; /* may be NULL */
 }
diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h
index b5917d6c63002e617d94f09c84a05a078ceb2fc9..22dae930e4c7436d3269066a01f21ca7371289f0 100644
--- a/src/core/lib/surface/channel.h
+++ b/src/core/lib/surface/channel.h
@@ -34,7 +34,6 @@
 #ifndef GRPC_CORE_LIB_SURFACE_CHANNEL_H
 #define GRPC_CORE_LIB_SURFACE_CHANNEL_H
 
-#include "src/core/ext/client_config/subchannel_factory.h"
 #include "src/core/lib/channel/channel_stack.h"
 #include "src/core/lib/surface/channel_stack_type.h"
 
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index fa5f84dedf3c261b990818cae79e59d8819d1a96..292882daf27cc1852462238a6cfd10ad0c50bf09 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -85,6 +85,7 @@ CORE_SOURCE_FILES = [
   'src/core/ext/census/tracing.c',
   'src/core/ext/client_config/channel_connectivity.c',
   'src/core/ext/client_config/client_channel.c',
+  'src/core/ext/client_config/client_channel_factory.c',
   'src/core/ext/client_config/client_config.c',
   'src/core/ext/client_config/connector.c',
   'src/core/ext/client_config/default_initial_connect_string.c',
@@ -96,7 +97,6 @@ CORE_SOURCE_FILES = [
   'src/core/ext/client_config/resolver_factory.c',
   'src/core/ext/client_config/resolver_registry.c',
   'src/core/ext/client_config/subchannel.c',
-  'src/core/ext/client_config/subchannel_factory.c',
   'src/core/ext/client_config/subchannel_index.c',
   'src/core/ext/client_config/uri_parser.c',
   'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
diff --git a/test/core/client_config/resolvers/dns_resolver_connectivity_test.c b/test/core/client_config/resolvers/dns_resolver_connectivity_test.c
index 091257fbb63c173f75123314d12061c7982edad2..2322aa688a40d026e22e0c6510617c66d373b426 100644
--- a/test/core/client_config/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_config/resolvers/dns_resolver_connectivity_test.c
@@ -41,20 +41,28 @@
 #include "src/core/lib/iomgr/timer.h"
 #include "test/core/util/test_config.h"
 
-static void subchannel_factory_ref(grpc_subchannel_factory *scv) {}
-static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
-                                     grpc_subchannel_factory *scv) {}
-static grpc_subchannel *subchannel_factory_create_subchannel(
-    grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory,
+static void client_channel_factory_ref(grpc_client_channel_factory *scv) {}
+static void client_channel_factory_unref(grpc_exec_ctx *exec_ctx,
+                                         grpc_client_channel_factory *scv) {}
+static grpc_subchannel *client_channel_factory_create_subchannel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory,
     grpc_subchannel_args *args) {
   return NULL;
 }
 
-static const grpc_subchannel_factory_vtable sc_vtable = {
-    subchannel_factory_ref, subchannel_factory_unref,
-    subchannel_factory_create_subchannel};
+static grpc_channel *client_channel_factory_create_channel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
+    const char *target, grpc_client_channel_type type,
+    grpc_channel_args *args) {
+  GPR_UNREACHABLE_CODE(return NULL);
+}
+
+static const grpc_client_channel_factory_vtable sc_vtable = {
+    client_channel_factory_ref, client_channel_factory_unref,
+    client_channel_factory_create_subchannel,
+    client_channel_factory_create_channel};
 
-static grpc_subchannel_factory sc_factory = {&sc_vtable};
+static grpc_client_channel_factory cc_factory = {&sc_vtable};
 
 static gpr_mu g_mu;
 static bool g_fail_resolution = true;
@@ -84,7 +92,7 @@ static grpc_resolver *create_resolver(const char *name) {
   grpc_resolver_args args;
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  args.subchannel_factory = &sc_factory;
+  args.client_channel_factory = &cc_factory;
   grpc_resolver *resolver =
       grpc_resolver_factory_create_resolver(factory, &args);
   grpc_resolver_factory_unref(factory);
diff --git a/test/core/client_config/resolvers/dns_resolver_test.c b/test/core/client_config/resolvers/dns_resolver_test.c
index ce95c656e6647ddd853fbfcfb1ac766e112b753d..21dc99cadd8f7274f8f693fbaf5e158ce189ce46 100644
--- a/test/core/client_config/resolvers/dns_resolver_test.c
+++ b/test/core/client_config/resolvers/dns_resolver_test.c
@@ -38,20 +38,28 @@
 #include "src/core/ext/client_config/resolver_registry.h"
 #include "test/core/util/test_config.h"
 
-static void subchannel_factory_ref(grpc_subchannel_factory *scv) {}
-static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
-                                     grpc_subchannel_factory *scv) {}
-static grpc_subchannel *subchannel_factory_create_subchannel(
-    grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory,
+static void client_channel_factory_ref(grpc_client_channel_factory *scv) {}
+static void client_channel_factory_unref(grpc_exec_ctx *exec_ctx,
+                                         grpc_client_channel_factory *scv) {}
+static grpc_subchannel *client_channel_factory_create_subchannel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory,
     grpc_subchannel_args *args) {
   GPR_UNREACHABLE_CODE(return NULL);
 }
 
-static const grpc_subchannel_factory_vtable sc_vtable = {
-    subchannel_factory_ref, subchannel_factory_unref,
-    subchannel_factory_create_subchannel};
+static grpc_channel *client_channel_factory_create_channel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
+    const char *target, grpc_client_channel_type type,
+    grpc_channel_args *args) {
+  GPR_UNREACHABLE_CODE(return NULL);
+}
+
+static const grpc_client_channel_factory_vtable sc_vtable = {
+    client_channel_factory_ref, client_channel_factory_unref,
+    client_channel_factory_create_subchannel,
+    client_channel_factory_create_channel};
 
-static grpc_subchannel_factory sc_factory = {&sc_vtable};
+static grpc_client_channel_factory cc_factory = {&sc_vtable};
 
 static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -63,7 +71,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  args.subchannel_factory = &sc_factory;
+  args.client_channel_factory = &cc_factory;
   resolver = grpc_resolver_factory_create_resolver(factory, &args);
   GPR_ASSERT(resolver != NULL);
   GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds");
diff --git a/test/core/client_config/resolvers/sockaddr_resolver_test.c b/test/core/client_config/resolvers/sockaddr_resolver_test.c
index bee66fa28b3b13c60911a4d0f1e2bf3ec41c809d..b11546b6b1cb18d6eaf8d3cb262e48ac88ee48c5 100644
--- a/test/core/client_config/resolvers/sockaddr_resolver_test.c
+++ b/test/core/client_config/resolvers/sockaddr_resolver_test.c
@@ -38,20 +38,28 @@
 #include "src/core/ext/client_config/resolver_registry.h"
 #include "test/core/util/test_config.h"
 
-static void subchannel_factory_ref(grpc_subchannel_factory *scv) {}
-static void subchannel_factory_unref(grpc_exec_ctx *exec_ctx,
-                                     grpc_subchannel_factory *scv) {}
-static grpc_subchannel *subchannel_factory_create_subchannel(
-    grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory,
+static void client_channel_factory_ref(grpc_client_channel_factory *scv) {}
+static void client_channel_factory_unref(grpc_exec_ctx *exec_ctx,
+                                         grpc_client_channel_factory *scv) {}
+static grpc_subchannel *client_channel_factory_create_subchannel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory,
     grpc_subchannel_args *args) {
   GPR_UNREACHABLE_CODE(return NULL);
 }
 
-static const grpc_subchannel_factory_vtable sc_vtable = {
-    subchannel_factory_ref, subchannel_factory_unref,
-    subchannel_factory_create_subchannel};
+static grpc_channel *client_channel_factory_create_channel(
+    grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory,
+    const char *target, grpc_client_channel_type type,
+    grpc_channel_args *args) {
+  GPR_UNREACHABLE_CODE(return NULL);
+}
+
+static const grpc_client_channel_factory_vtable sc_vtable = {
+    client_channel_factory_ref, client_channel_factory_unref,
+    client_channel_factory_create_subchannel,
+    client_channel_factory_create_channel};
 
-static grpc_subchannel_factory sc_factory = {&sc_vtable};
+static grpc_client_channel_factory cc_factory = {&sc_vtable};
 
 static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -63,7 +71,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) {
   GPR_ASSERT(uri);
   memset(&args, 0, sizeof(args));
   args.uri = uri;
-  args.subchannel_factory = &sc_factory;
+  args.client_channel_factory = &cc_factory;
   resolver = grpc_resolver_factory_create_resolver(factory, &args);
   GPR_ASSERT(resolver != NULL);
   GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds");
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index a940321c4cc018b34f2a68945b5b9355f80aca08..d62327d6718d1cb5c3f92b08915a7953b8b74642 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -780,6 +780,7 @@ src/core/ext/census/grpc_filter.h \
 src/core/ext/census/mlog.h \
 src/core/ext/census/rpc_metric_id.h \
 src/core/ext/client_config/client_channel.h \
+src/core/ext/client_config/client_channel_factory.h \
 src/core/ext/client_config/client_config.h \
 src/core/ext/client_config/connector.h \
 src/core/ext/client_config/initial_connect_string.h \
@@ -790,7 +791,6 @@ src/core/ext/client_config/resolver.h \
 src/core/ext/client_config/resolver_factory.h \
 src/core/ext/client_config/resolver_registry.h \
 src/core/ext/client_config/subchannel.h \
-src/core/ext/client_config/subchannel_factory.h \
 src/core/ext/client_config/subchannel_index.h \
 src/core/ext/client_config/uri_parser.h \
 src/core/ext/lb_policy/grpclb/load_balancer_api.h \
@@ -919,6 +919,7 @@ src/core/ext/census/placeholders.c \
 src/core/ext/census/tracing.c \
 src/core/ext/client_config/channel_connectivity.c \
 src/core/ext/client_config/client_channel.c \
+src/core/ext/client_config/client_channel_factory.c \
 src/core/ext/client_config/client_config.c \
 src/core/ext/client_config/connector.c \
 src/core/ext/client_config/default_initial_connect_string.c \
@@ -930,7 +931,6 @@ src/core/ext/client_config/resolver.c \
 src/core/ext/client_config/resolver_factory.c \
 src/core/ext/client_config/resolver_registry.c \
 src/core/ext/client_config/subchannel.c \
-src/core/ext/client_config/subchannel_factory.c \
 src/core/ext/client_config/subchannel_index.c \
 src/core/ext/client_config/uri_parser.c \
 src/core/ext/lb_policy/grpclb/load_balancer_api.c \
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 3b03b57d755a8a59fd31753cc3aae53bc394c237..59e792b372bc17fd9af0f0bc7914c8c196804dab 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -4008,6 +4008,7 @@
       "src/core/ext/census/mlog.h", 
       "src/core/ext/census/rpc_metric_id.h", 
       "src/core/ext/client_config/client_channel.h", 
+      "src/core/ext/client_config/client_channel_factory.h", 
       "src/core/ext/client_config/client_config.h", 
       "src/core/ext/client_config/connector.h", 
       "src/core/ext/client_config/initial_connect_string.h", 
@@ -4018,7 +4019,6 @@
       "src/core/ext/client_config/resolver_factory.h", 
       "src/core/ext/client_config/resolver_registry.h", 
       "src/core/ext/client_config/subchannel.h", 
-      "src/core/ext/client_config/subchannel_factory.h", 
       "src/core/ext/client_config/subchannel_index.h", 
       "src/core/ext/client_config/uri_parser.h", 
       "src/core/ext/lb_policy/grpclb/load_balancer_api.h", 
@@ -4171,6 +4171,8 @@
       "src/core/ext/client_config/channel_connectivity.c", 
       "src/core/ext/client_config/client_channel.c", 
       "src/core/ext/client_config/client_channel.h", 
+      "src/core/ext/client_config/client_channel_factory.c", 
+      "src/core/ext/client_config/client_channel_factory.h", 
       "src/core/ext/client_config/client_config.c", 
       "src/core/ext/client_config/client_config.h", 
       "src/core/ext/client_config/connector.c", 
@@ -4192,8 +4194,6 @@
       "src/core/ext/client_config/resolver_registry.h", 
       "src/core/ext/client_config/subchannel.c", 
       "src/core/ext/client_config/subchannel.h", 
-      "src/core/ext/client_config/subchannel_factory.c", 
-      "src/core/ext/client_config/subchannel_factory.h", 
       "src/core/ext/client_config/subchannel_index.c", 
       "src/core/ext/client_config/subchannel_index.h", 
       "src/core/ext/client_config/uri_parser.c", 
@@ -4622,6 +4622,7 @@
       "src/core/ext/census/mlog.h", 
       "src/core/ext/census/rpc_metric_id.h", 
       "src/core/ext/client_config/client_channel.h", 
+      "src/core/ext/client_config/client_channel_factory.h", 
       "src/core/ext/client_config/client_config.h", 
       "src/core/ext/client_config/connector.h", 
       "src/core/ext/client_config/initial_connect_string.h", 
@@ -4632,7 +4633,6 @@
       "src/core/ext/client_config/resolver_factory.h", 
       "src/core/ext/client_config/resolver_registry.h", 
       "src/core/ext/client_config/subchannel.h", 
-      "src/core/ext/client_config/subchannel_factory.h", 
       "src/core/ext/client_config/subchannel_index.h", 
       "src/core/ext/client_config/uri_parser.h", 
       "src/core/ext/lb_policy/grpclb/load_balancer_api.h", 
@@ -4770,6 +4770,8 @@
       "src/core/ext/client_config/channel_connectivity.c", 
       "src/core/ext/client_config/client_channel.c", 
       "src/core/ext/client_config/client_channel.h", 
+      "src/core/ext/client_config/client_channel_factory.c", 
+      "src/core/ext/client_config/client_channel_factory.h", 
       "src/core/ext/client_config/client_config.c", 
       "src/core/ext/client_config/client_config.h", 
       "src/core/ext/client_config/connector.c", 
@@ -4791,8 +4793,6 @@
       "src/core/ext/client_config/resolver_registry.h", 
       "src/core/ext/client_config/subchannel.c", 
       "src/core/ext/client_config/subchannel.h", 
-      "src/core/ext/client_config/subchannel_factory.c", 
-      "src/core/ext/client_config/subchannel_factory.h", 
       "src/core/ext/client_config/subchannel_index.c", 
       "src/core/ext/client_config/subchannel_index.h", 
       "src/core/ext/client_config/uri_parser.c", 
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 775b998446301031240b0b08e0fbd100acd1d1c1..c6494638735f2c432a21156eb9f5ee1a4feeb57a 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -289,6 +289,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\mlog.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\rpc_metric_id.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_config.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\connector.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.h" />
@@ -299,7 +300,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver_registry.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h" />
@@ -441,6 +441,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_config.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\connector.c">
@@ -463,8 +465,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_factory.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index e97c0ddf3f7b46c3f3299f505e8c7f5c4c19a665..47a030e47eda6f59219df82502034dddfe1fd336 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -34,6 +34,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.c">
+      <Filter>src\core\ext\client_config</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_config.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
@@ -67,9 +70,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_factory.c">
-      <Filter>src\core\ext\client_config</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
@@ -551,6 +551,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.h">
+      <Filter>src\core\ext\client_config</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_config.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
@@ -581,9 +584,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_factory.h">
-      <Filter>src\core\ext\client_config</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 1a957774403491b63439294fe1d2d632832a1b2c..fe1331f3000485f9515058da7fbb6837a5f27154 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -279,6 +279,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\mlog.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\rpc_metric_id.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_config.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\connector.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\initial_connect_string.h" />
@@ -289,7 +290,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\resolver_registry.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_factory.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h" />
@@ -417,6 +417,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_config.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\connector.c">
@@ -439,8 +441,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_factory.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 0db6685fe2bba567e81017ad588b9a48d7af8669..79156621325d0789cd0db3824f6ae776f417f9ae 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -34,6 +34,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.c">
+      <Filter>src\core\ext\client_config</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_config.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
@@ -67,9 +70,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_factory.c">
-      <Filter>src\core\ext\client_config</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
@@ -488,6 +488,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel_factory.h">
+      <Filter>src\core\ext\client_config</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\client_config.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
@@ -518,9 +521,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_factory.h">
-      <Filter>src\core\ext\client_config</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>