diff --git a/lib/wp/factory.c b/lib/wp/factory.c
index 7ce68bfacc5c97e710017ba5fc3e4dcf5ca2ffb3..f8c71d468731d90d94b05d57375954943b99b05b 100644
--- a/lib/wp/factory.c
+++ b/lib/wp/factory.c
@@ -12,6 +12,7 @@ struct _WpFactory
 {
   GObject parent;
 
+  GWeakRef core;
   gchar *name;
   GQuark name_quark;
   WpFactoryFunc create_object;
@@ -29,6 +30,7 @@ wp_factory_finalize (GObject * obj)
 {
   WpFactory * self = WP_FACTORY (obj);
 
+  g_weak_ref_clear (&self->core);
   g_free (self->name);
 
   G_OBJECT_CLASS (wp_factory_parent_class)->finalize (obj);
@@ -50,6 +52,7 @@ wp_factory_new (WpCore * core, const gchar * name, WpFactoryFunc func)
   g_return_val_if_fail (func != NULL, NULL);
 
   f = g_object_new (WP_TYPE_FACTORY, NULL);
+  g_weak_ref_init (&f->core, core);
   f->name = g_strdup (name);
   f->name_quark = g_quark_from_string (f->name);
   f->create_object = func;
@@ -66,6 +69,18 @@ wp_factory_get_name (WpFactory * self)
   return self->name;
 }
 
+/**
+ * wp_factory_get_core:
+ * @self: the factory
+ *
+ * Returns: (transfer full): the core on which this factory is registered
+ */
+WpCore *
+wp_factory_get_core (WpFactory * self)
+{
+  return g_weak_ref_get (&self->core);
+}
+
 gpointer
 wp_factory_create_object (WpFactory * self, GType type, GVariant * properties)
 {
diff --git a/lib/wp/factory.h b/lib/wp/factory.h
index 83737029b6f282cec82abfcf57e5d620f173c898..efb905d0ae3467bebdaabaa895a05917f03527ba 100644
--- a/lib/wp/factory.h
+++ b/lib/wp/factory.h
@@ -23,6 +23,7 @@ WpFactory * wp_factory_new (WpCore * core, const gchar * name,
     WpFactoryFunc func);
 
 const gchar * wp_factory_get_name (WpFactory * self);
+WpCore * wp_factory_get_core (WpFactory * self);
 gpointer wp_factory_create_object (WpFactory * self, GType type,
     GVariant * properties);
 
diff --git a/lib/wp/module.c b/lib/wp/module.c
index 6f4f734a9e33e18c9947f5cfded1087edc76b91f..3afea3ddae5394eeb70c06f95dff2454a97ff85a 100644
--- a/lib/wp/module.c
+++ b/lib/wp/module.c
@@ -17,6 +17,8 @@ typedef void (*WpModuleInitFunc) (WpModule *, WpCore *, GVariant *);
 struct _WpModule
 {
   GObject parent;
+
+  GWeakRef core;
   GVariant *properties;
   GDestroyNotify destroy;
   gpointer destroy_data;
@@ -37,6 +39,7 @@ wp_module_finalize (GObject * object)
   if (self->destroy)
     self->destroy (self->destroy_data);
   g_clear_pointer (&self->properties, g_variant_unref);
+  g_weak_ref_clear (&self->core);
 
   G_OBJECT_CLASS (wp_module_parent_class)->finalize (object);
 }
@@ -106,8 +109,10 @@ wp_module_load (WpCore * core, const gchar * abi,
 {
   g_autoptr (WpModule) module = NULL;
 
+  module = g_object_new (WP_TYPE_MODULE, NULL);
+  g_weak_ref_init (&module->core, core);
+
   if (!g_strcmp0 (abi, "C")) {
-    module = g_object_new (WP_TYPE_MODULE, NULL);
     if (!wp_module_load_c (module, core, module_name, args, error))
       return NULL;
   } else {
@@ -118,6 +123,7 @@ wp_module_load (WpCore * core, const gchar * abi,
 
   wp_core_register_global (core, g_quark_from_string (module_name),
       g_object_ref (module), g_object_unref);
+
   return module;
 }
 
@@ -127,6 +133,18 @@ wp_module_get_properties (WpModule * self)
   return self->properties;
 }
 
+/**
+ * wp_module_get_core:
+ * @self: the module
+ *
+ * Returns: (transfer full): the core on which this module is registered
+ */
+WpCore *
+wp_module_get_core (WpModule * self)
+{
+  return g_weak_ref_get (&self->core);
+}
+
 void
 wp_module_set_destroy_callback (WpModule * self, GDestroyNotify callback,
     gpointer data)
diff --git a/lib/wp/module.h b/lib/wp/module.h
index c157a30648338ecb07139583f005d9fd27381ede..553ecac513c59c3d6fc78acc173a600aa7041f17 100644
--- a/lib/wp/module.h
+++ b/lib/wp/module.h
@@ -20,6 +20,7 @@ WpModule * wp_module_load (WpCore * core, const gchar * abi,
     const gchar * module_name, GVariant * args, GError ** error);
 
 GVariant * wp_module_get_properties (WpModule * module);
+WpCore * wp_module_get_core (WpModule * module);
 
 void wp_module_set_destroy_callback (WpModule * module, GDestroyNotify callback,
     gpointer data);