How to let extension users choose cache system?
1. CRM_Utils_Cache::create()

When looking through the list of cache drivers, you see options like Memcache, Memcached, and Redis. Generally there's little reason why a deployment would use all three -- rather, the typical question this:


Do we have any kind of high-speed/shared/memory-based cache? If so, use it. 
Do we have any kind of SQL-backed cache? If so, use it.
Otherwise, use an ephemeral array() (for the duration each request)


In v4.7, CRM_Utils_Cache::create() is a factory function which accepts an ordered list of drivers, and it picks the first one that's usable, e.g.

$myCache = CRM_Utils_Cache::create(array(
  'name' =&gt; 'somethingsomething',
  'type' =&gt; array('*memory*', 'SqlGroup', 'ArrayCache'),
));


This aims to address the typical use-case by making it unnecessary for the admin to configure anything extra for your specific extension.

Your extension would need to retain a copy of that cache object, e.g.

function myextension_cache() {
  if (!isset(Civi::$statics['myextension_cache'])) {
    Civi::$statics['myextension_cache'] = CRM_Utils_Cache::create(array(
      'name' =&gt; 'somethingsomething',
      'type' =&gt; array('*memory*', 'SqlGroup', 'ArrayCache'),
    ));
  }
  return Civi::$statics['myextension_cache'];
}


I believe this answers the typical requirement/issue when someone wants to configure the extension's cache, but it doesn't literally answer the question...

2. Named services and caching

The Symfony service container is a general-purpose tool for naming and tracking a bunch of objects -- cache services, database services, entity-repositories, etc. Rather than have a hundred functions like myextension_cache() which hard-code the factory, we put all the factories together in the container. This pattern improves our leverage; in principle, you can expose the container to different processes, e.g.


Reading multiple YAML/XML files to configure the container
Allowing extensions/hooks to alter the container
Allowing site admins to alter the container
Allowing dev-tools and admin-tools to inspect the container


For this reason, new caches in core tend to be created through the container, e.g.


Civi::cache() is equivalent to Civi::container()-&gt;get('cache.default')
Civi::cache('js_strings') is equivalent to Civi::container()-&gt;get('cache.js_strings')


However, at this point, the container in Civi needs improvement. For example, you can alter the container via hook_civicrm_container, but there's no YAML/XML/annotation mechanism for updating the container, and there's no mechanism for site-admins to modify services via config file (civicrm.settings.php). 

The long-term goal is to shift more service-management into a container so that questions like "How does a site admin customize service X?" have a categorical answer. Improving the container is very much patch-welcome.