diff --git a/include/fggl/ds/graph.hpp b/include/fggl/ds/graph.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f88ff5c61adf292b1e43beffc2b9c64adbdb747d
--- /dev/null
+++ b/include/fggl/ds/graph.hpp
@@ -0,0 +1,142 @@
+/*
+ * This file is part of FGGL.
+ *
+ * FGGL is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * FGGL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along with FGGL.
+ * If not, see <https://www.gnu.org/licenses/>.
+ */
+
+//
+// Created by webpigeon on 25/03/23.
+//
+
+#ifndef FGGL_DS_GRAPH_HPP
+#define FGGL_DS_GRAPH_HPP
+
+#include <map>
+#include <vector>
+#include <queue>
+#include <stack>
+#include <set>
+
+namespace fggl::ds {
+
+	template<typename T>
+	class DirectedGraph {
+		public:
+
+			/**
+			 * Add a single edge to the graph.
+			 *
+			 * If the entry does not already exist, this will create the entry before adding the dependencies to it.
+			 * If the entry already exists, this will append the provided dependencies to its existing list.
+			 *
+			 * @param start the entry which depends something else
+			 * @param end the thing it depends on
+			 */
+			inline void addEdge(T start, const T end) {
+				m_edges[start].push_back(end);
+				m_edges[end];
+			}
+
+			/**
+			 * Add a single vertex to the graph.
+			 */
+			 inline void addVertex(T vertex) {
+				 m_edges[vertex];
+			 }
+
+			/**
+			 * Add a series of dependencies for an entry.
+			 *
+			 * If the entry does not already exist, this will create the entry before adding the dependencies to it.
+			 * If the entry already exists, this will append the provided dependencies to its existing list.
+			 *
+			 * @param name the entry having dependencies added
+			 * @param dependencies the things it depends on
+			 */
+			void addEdges(const T &name, const std::vector<T> &dependencies) {
+				auto existing = m_edges.find(name);
+				if (existing == m_edges.end()) {
+					m_edges[name] = dependencies;
+				} else {
+					existing->second.insert(existing->second.end(), dependencies.begin(), dependencies.end());
+				}
+			}
+
+			/**
+			 * Clear all currently stored dependencies.
+			 *
+			 * This method will result in the dependency graph being empty, with no known modules.
+			 */
+			inline void clear() {
+				m_edges.clear();
+			}
+
+			inline auto begin() const {
+				return m_edges.begin();
+			}
+
+			inline auto end() const {
+				return m_edges.end();
+			}
+
+			bool getOrder(std::stack<T> &stack) {
+				std::set<T> visited{};
+
+				for (const auto &module : m_edges) {
+					if (!visited.contains(module.first)) {
+						sortUtil(module.first, visited, stack);
+					}
+				}
+
+				return true;
+			}
+
+			bool getOrderRev(std::queue<T> &stack) {
+				std::set<T> visited{};
+
+				for (const auto &module : m_edges) {
+					if (!visited.contains(module.first)) {
+						sortUtilRev(module.first, visited, stack);
+					}
+				}
+
+				return true;
+			}
+
+		private:
+			std::map<T, std::vector<T>> m_edges;
+
+			void sortUtil(T idx, std::set<T> &visited, std::stack<T> &stack) {
+				visited.emplace(idx);
+
+				for (auto dep : m_edges.at(idx)) {
+					if (!visited.contains(dep))
+						sortUtil(dep, visited, stack);
+				}
+
+				stack.push(idx);
+			}
+
+			void sortUtilRev(T idx, std::set<T> &visited, std::queue<T> &stack) {
+				visited.emplace(idx);
+
+				for (auto dep : m_edges.at(idx)) {
+					if (!visited.contains(dep))
+						sortUtilRev(dep, visited, stack);
+				}
+
+				stack.push(idx);
+			}
+	};
+
+} // namespace fggl::ds
+
+#endif //FGGL_DS_GRAPH_HPP
diff --git a/include/fggl/modules/manager.hpp b/include/fggl/modules/manager.hpp
index 522553a05b0334e9ecb760719fab006488dc725c..48acb0c2d8aa6aaa49d76cc3c8bfbdcf49b3cc4d 100644
--- a/include/fggl/modules/manager.hpp
+++ b/include/fggl/modules/manager.hpp
@@ -21,6 +21,7 @@
 
 #include "fggl/modules/module.hpp"
 #include "fggl/debug/logging.hpp"
+#include "fggl/ds/graph.hpp"
 
 #include <queue>
 #include <vector>
@@ -31,108 +32,6 @@
 
 namespace fggl::modules {
 
-	/**
-	 * A class used for representing a Directed Acyclic Graph.
-	 *
-	 * This class is mostly used for establishing the loading order of classes for module loading.
-	 *
-	 * @tparam T the type being represented
-	 */
-	template<typename T>
-	class DependencyGraph {
-		public:
-			DependencyGraph() = default;
-
-			/**
-			 * Clear all currently stored dependencies.
-			 *
-			 * This method will result in the dependency graph being empty, with no known modules.
-			 */
-			void clear() {
-				m_dependencies.clear();
-			}
-
-			/**
-			 * Add a series of dependencies for an entry.
-			 *
-			 * If the entry does not already exist, this will create the entry before adding the dependencies to it.
-			 * If the entry already exists, this will append the provided dependencies to its existing list.
-			 *
-			 * @param name the entry having dependencies added
-			 * @param dependencies the things it depends on
-			 */
-			void addAll(const T &name, const std::vector<T> &dependencies) {
-				auto existing = m_dependencies.find(name);
-				if (existing == m_dependencies.end()) {
-					m_dependencies[name] = dependencies;
-				} else {
-					existing->second.insert(existing->second.end(), dependencies.begin(), dependencies.end());
-				}
-			}
-
-			/**
-			 * Add a single dependency to the graph.
-			 *
-			 * If the entry does not already exist, this will create the entry before adding the dependencies to it.
-			 * If the entry already exists, this will append the provided dependencies to its existing list.
-			 *
-			 * @param name the entry which depends something else
-			 * @param depends the thing it depends on
-			 */
-			void add(const T &name, const T &depends) {
-				m_dependencies[name].push_back(depends);
-			}
-
-			bool getOrder(std::stack<T> &stack) {
-				std::set<T> visited{};
-
-				for (const auto &module : m_dependencies) {
-					if (!visited.contains(module.first)) {
-						sortUtil(module.first, visited, stack);
-					}
-				}
-
-				return true;
-			}
-
-			bool getOrderRev(std::queue<T> &stack) {
-				std::set<T> visited{};
-
-				for (const auto &module : m_dependencies) {
-					if (!visited.contains(module.first)) {
-						sortUtilRev(module.first, visited, stack);
-					}
-				}
-
-				return true;
-			}
-
-		private:
-			std::map<T, std::vector<T>> m_dependencies;
-
-			void sortUtil(T idx, std::set<T> &visited, std::stack<T> &stack) {
-				visited.emplace(idx);
-
-				for (auto dep : m_dependencies.at(idx)) {
-					if (!visited.contains(dep))
-						sortUtil(dep, visited, stack);
-				}
-
-				stack.push(idx);
-			}
-
-			void sortUtilRev(T idx, std::set<T> &visited, std::queue<T> &stack) {
-				visited.emplace(idx);
-
-				for (auto dep : m_dependencies.at(idx)) {
-					if (!visited.contains(dep))
-						sortUtilRev(dep, visited, stack);
-				}
-
-				stack.push(idx);
-			}
-	};
-
 	/**
 	 * Store and initialise modules present in the engine.
 	 *
@@ -191,7 +90,7 @@ namespace fggl::modules {
 				// resolve links between modules
 				for (auto &moduleItr : m_modules) {
 					if (moduleItr.second.depends.empty()) {
-						m_dependencies.addAll(moduleItr.first, {});
+						m_dependencies.addVertex(moduleItr.first);
 						continue;
 					}
 
@@ -207,7 +106,7 @@ namespace fggl::modules {
 							return false;
 						}
 
-						m_dependencies.add(moduleItr.first, provider->second);
+						m_dependencies.addEdge(moduleItr.first, provider->second);
 					}
 				}
 				return true;
@@ -267,7 +166,7 @@ namespace fggl::modules {
 			bool m_locked = false;
 			Services m_services;
 			std::map<ModuleIdentifier, Config> m_modules;
-			DependencyGraph<ModuleIdentifier> m_dependencies;
+			ds::DirectedGraph<ModuleIdentifier> m_dependencies;
 			std::map<ServiceName, ModuleIdentifier> m_serviceProviders;
 
 	};
diff --git a/include/fggl/modules/service.hpp b/include/fggl/modules/service.hpp
index a1b679b3a4bd874594d4f63b7d9bdb28d8486f29..75a42606de64c5b0e350a8c362ada2898e8b2659 100644
--- a/include/fggl/modules/service.hpp
+++ b/include/fggl/modules/service.hpp
@@ -43,7 +43,6 @@ namespace fggl::modules {
 		public:
 			template<ServiceType Svc, Derived<Svc> Impl, typename ...Args>
 			void bind(Args... args) {
-				static_assert(std::is_base_of_v<Svc, Impl>, "Service type must be assignable from implementation type");
 				m_services[Svc::service] = std::make_shared<Impl>(args...);
 			}
 
@@ -72,4 +71,6 @@ namespace fggl::modules {
 
 } // namespace fggl::modules
 
+
+
 #endif //FGGL_MODULES_SERVICE_HPP