diff --git a/components/common/cpp/include/ftl/configurable.hpp b/components/common/cpp/include/ftl/configurable.hpp
index c1f903b61df4004e458c54f243fd0014c69ff96f..59090a58521a9559e0aa398e91a8fe38ef00a7eb 100644
--- a/components/common/cpp/include/ftl/configurable.hpp
+++ b/components/common/cpp/include/ftl/configurable.hpp
@@ -15,6 +15,15 @@
 
 namespace ftl {
 
+class Configurable;
+
+namespace config {
+struct Event {
+	Configurable *entity;
+	std::string name;
+};
+}
+
 /**
  * The Configurable class should be inherited by any entity that is to be
  * configured using json objects. Additionally, any such object can then be
@@ -39,6 +48,9 @@ class Configurable {
 	 */
 	void required(const char *f, const std::vector<std::tuple<std::string, std::string, std::string>> &r);
 
+	/**
+	 * Return raw JSON entity for this Configurable.
+	 */
 	nlohmann::json &getConfig() { return config_; }
 
 	/**
@@ -68,18 +80,26 @@ class Configurable {
 		_trigger(name);
 	}
 
+	/**
+	 * Create or find existing configurable object of given type from the
+	 * given property name. Additional constructor arguments can also be
+	 * provided. Any kind of failure results in a nullptr being returned.
+	 */
+	template <typename T, typename... ARGS>
+	T *create(const std::string &name, ARGS ...args);
+
 	/**
 	 * Add callback for whenever a specified property changes value.
 	 * @param prop Name of property to watch
 	 * @param callback A function object that will be called on change.
 	 */
-	void on(const std::string &prop, std::function<void(Configurable*, const std::string&)>);
+	void on(const std::string &prop, std::function<void(const config::Event&)>);
 
 	protected:
 	nlohmann::json config_;
 
 	private:
-	std::map<std::string, std::list<std::function<void(Configurable*, const std::string&)>>> observers_; 
+	std::map<std::string, std::list<std::function<void(const config::Event&)>>> observers_; 
 
 	void _trigger(const std::string &name);
 
@@ -124,4 +144,9 @@ std::optional<T> ftl::Configurable::get(const std::string &name) {
 	}
 }
 
+template <typename T, typename... ARGS>
+T *ftl::Configurable::create(const std::string &name, ARGS ...args) {
+	return ftl::config::create<T>(this, name, args...);
+}
+
 #endif  // _FTL_CONFIGURABLE_HPP_
diff --git a/components/common/cpp/src/configurable.cpp b/components/common/cpp/src/configurable.cpp
index d770ae6e7003a21bc4a9d15d9c523cb0f0339f84..81f9092b8e316af4fb4dc13f104b8d3b0b77af30 100644
--- a/components/common/cpp/src/configurable.cpp
+++ b/components/common/cpp/src/configurable.cpp
@@ -30,7 +30,7 @@ void Configurable::_trigger(const string &name) {
 	if (ix != observers_.end()) {
 		for (auto &f : (*ix).second) {
 			try {
-				f(this, name);
+				f({this, name});
 			} catch(...) {
 				LOG(ERROR) << "Exception in event handler for '" << name << "'";
 			}
@@ -38,7 +38,7 @@ void Configurable::_trigger(const string &name) {
 	}
 }
 
-void Configurable::on(const string &prop, function<void(Configurable*, const string&)> f) {
+void Configurable::on(const string &prop, function<void(const ftl::config::Event&)> f) {
 	auto ix = observers_.find(prop);
 	if (ix == observers_.end()) {
 		observers_[prop] = {f};
diff --git a/components/common/cpp/test/configurable_unit.cpp b/components/common/cpp/test/configurable_unit.cpp
index 7855438a64114825ec54c54e8bb1a9848066de08..83148e9d41196e055c95a32ab3d93217af72baec 100644
--- a/components/common/cpp/test/configurable_unit.cpp
+++ b/components/common/cpp/test/configurable_unit.cpp
@@ -38,7 +38,7 @@ SCENARIO( "Configurable::on()" ) {
 		Configurable cfg(json);
 		bool trig = false;
 
-		cfg.on("test", [&trig](Configurable *c, const string &n) {
+		cfg.on("test", [&trig](const ftl::config::Event &e) {
 			trig = true;
 		});
 
@@ -53,10 +53,10 @@ SCENARIO( "Configurable::on()" ) {
 		bool trig1 = false;
 		bool trig2 = false;
 
-		cfg.on("test", [&trig1](Configurable *c, const string &n) {
+		cfg.on("test", [&trig1](const ftl::config::Event &e) {
 			trig1 = true;
 		});
-		cfg.on("test", [&trig2](Configurable *c, const string &n) {
+		cfg.on("test", [&trig2](const ftl::config::Event &e) {
 			trig2 = true;
 		});