diff --git a/gio/gsettingsbackend.c b/gio/gsettingsbackend.c
index e33d479..cbf7221 100644
--- a/gio/gsettingsbackend.c
+++ b/gio/gsettingsbackend.c
@@ -19,10 +19,19 @@
 
 #include "gioalias.h"
 
+struct _GSettingsBackendPrivate
+{
+  gchar *context;
+};
+
 G_DEFINE_ABSTRACT_TYPE (GSettingsBackend, g_settings_backend, G_TYPE_OBJECT)
 
 static guint changed_signal;
 
+enum {
+  PROP_CONTEXT
+};
+
 /**
  * SECTION:gsettingsbackend
  * @short_description: an interface for settings backend implementations
@@ -265,8 +274,64 @@ g_settings_backend_subscribe (GSettingsBackend *backend,
 }
 
 static void
+g_settings_backend_set_property (GObject         *object,
+                                 guint            prop_id,
+                                 const GValue    *value,
+                                 GParamSpec      *pspec)
+{
+  GSettingsBackend *backend;
+
+  switch (prop_id)
+    {
+    case PROP_CONTEXT:
+      backend->priv->context = g_value_dup_string (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_settings_backend_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+  GSettingsBackend *backend;
+
+  switch (prop_id)
+    {
+    case PROP_CONTEXT:
+      g_value_set_string (value, backend->priv->context);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+g_settings_backend_finalize (GObject *object)
+{
+  GSettingsBackend *backend = G_SETTINGS_BACKEND (object);
+
+  g_free (backend->priv->context);
+
+  G_OBJECT_CLASS (g_settings_backend_parent_class)->finalize (object);
+}
+
+static void
 g_settings_backend_class_init (GSettingsBackendClass *class)
 {
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+  gobject_class->get_property = g_settings_backend_get_property;
+  gobject_class->set_property = g_settings_backend_set_property;
+  gobject_class->finalize = g_settings_backend_finalize;
+
+  g_type_class_add_private (class, sizeof (GSettingsBackendPrivate));
+
   /**
    * GSettingsBackend::changed:
    * @backend: the object on which the signal was emitted
@@ -297,6 +362,14 @@ g_settings_backend_class_init (GSettingsBackendClass *class)
                   4, G_TYPE_STRING | G_SIGNAL_TYPE_STATIC_SCOPE,
                   G_TYPE_STRV | G_SIGNAL_TYPE_STATIC_SCOPE,
                   G_TYPE_INT, G_TYPE_POINTER);
+
+  g_object_class_install_property (gobject_class, PROP_CONTEXT,
+                                   g_param_spec_string ("context",
+                                                        "Context",
+                                                        "A context to use when deciding which storage to use",
+                                                        NULL,
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
 }
 
 /**
@@ -317,7 +390,7 @@ g_settings_backend_create_tree (void)
 }
 
 static gpointer
-get_default_backend (gpointer user_data)
+get_default_backend (const gchar *context)
 {
   GIOExtension *extension = NULL;
   GIOExtensionPoint *point;
@@ -348,32 +421,91 @@ get_default_backend (gpointer user_data)
       extension = extensions->data;
     }
 
+  if (context)
+    {
+      GTypeClass *class;
+      const gchar **contexts;
+
+      class = g_io_extension_ref_class (extension);
+
+      contexts = g_settings_backend_class_get_supported_contexts (G_SETTINGS_BACKEND_CLASS (class));
+      if (contexts)
+        {
+          gint i;
+
+          for (i = 0; contexts[i]; i++)
+            {
+              if (strcmp (context, contexts[i]) == 0)
+                break;
+            }
+
+          if (contexts[i] == NULL)
+            {
+              g_type_class_unref (class);
+              return NULL;
+            }
+        }
+
+      g_type_class_unref (class);
+    }
+
   type = g_io_extension_get_type (extension);
 
-  return g_object_new (type, NULL);
+  return g_object_new (type, "context", context, NULL);
 }
 
 /**
  * g_settings_backend_get_default:
+ * @context: a context that might be used by the backend to determine
+ *     which storage to use
  * @returns: the default #GSettingsBackend
  *
  * Returns the default #GSettingsBackend. It is possible to override
  * the default by setting the <envvar>GSETTINGS_BACKEND</envvar>
  * environment variable to the name of a settings backend.
  *
+ * The @context parameter can be used to indicate that a different
+ * than the default storage is desired. E.g. the DConf backend lets
+ * you use "user", "system", "defaults" and "login" as contexts.
+ *
  * The user does not own the return value and it must not be freed.
  *
  * Since: 2.26
  **/
 GSettingsBackend *
-g_settings_backend_get_default (void)
+g_settings_backend_get_default (const gchar *context)
 {
-  static GOnce once = G_ONCE_INIT;
+  static GHashTable *backends;
+  GSettingsBackend *backend;
+
+  if (!backends)
+    backends = g_hash_table_new (g_str_hash, g_str_equal);
 
-  return g_once (&once, get_default_backend, NULL);
+  backend = g_hash_table_lookup (backends, context);
+
+  if (!backend)
+    {
+      backend = get_default_backend (context);
+
+      g_hash_table_insert (backends, g_strdup (context), backend);
+    }
+
+  return backend;
 }
 
 static void
 g_settings_backend_init (GSettingsBackend *backend)
 {
+  backend->priv = g_type_instance_get_private (backend, G_TYPE_SETTINGS_BACKEND);
 }
+
+const gchar **
+g_settings_backend_class_get_supported_contexts (GSettingsBackendClass *klass)
+{
+  if (klass->supported_contexts)
+    return (klass->supported_contexts) (klass);
+
+  return NULL;
+}
+
+
diff --git a/gio/gsettingsbackend.h b/gio/gsettingsbackend.h
index 4a0d0e1..4e05fc4 100644
--- a/gio/gsettingsbackend.h
+++ b/gio/gsettingsbackend.h
@@ -61,6 +61,8 @@ struct _GSettingsBackendClass
                                const gchar         *name);
   void        (*unsubscribe)  (GSettingsBackend    *backend,
                                const gchar         *name);
+
+  const gchar **(*supported_contexts) (GSettingsBackendClass *klass);
 };
 
 struct _GSettingsBackend
@@ -72,7 +74,7 @@ struct _GSettingsBackend
 };
 
 GType                           g_settings_backend_get_type             (void);
-GSettingsBackend *              g_settings_backend_get_default          (void);
+GSettingsBackend *              g_settings_backend_get_default          (const gchar *context);
 GTree *                         g_settings_backend_create_tree          (void);
 
 GVariant *                      g_settings_backend_read                 (GSettingsBackend    *backend,
@@ -102,6 +104,8 @@ void                            g_settings_backend_changed_tree         (GSettin
                                                                          GTree               *tree,
                                                                          gpointer             origin_tag);
 
+const gchar **g_settings_backend_class_get_supported_contexts (GSettingsBackendClass *klass);
+
 G_END_DECLS
 
 #endif /* _gsettingsbackend_h_ */
