diff --git a/packages/service_container/.gitignore b/packages/service_container/.gitignore
new file mode 100644
index 0000000..3cceda5
--- /dev/null
+++ b/packages/service_container/.gitignore
@@ -0,0 +1,7 @@
+# https://dart.dev/guides/libraries/private-files
+# Created by `dart pub`
+.dart_tool/
+
+# Avoid committing pubspec.lock for library packages; see
+# https://dart.dev/guides/libraries/private-files#pubspeclock.
+pubspec.lock
diff --git a/packages/service_container/CHANGELOG.md b/packages/service_container/CHANGELOG.md
new file mode 100644
index 0000000..effe43c
--- /dev/null
+++ b/packages/service_container/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 1.0.0
+
+- Initial version.
diff --git a/packages/service_container/LICENSE.md b/packages/service_container/LICENSE.md
new file mode 100644
index 0000000..0fd0d03
--- /dev/null
+++ b/packages/service_container/LICENSE.md
@@ -0,0 +1,10 @@
+The MIT License (MIT)
+
+The Laravel Framework is Copyright (c) Taylor Otwell
+The Fabric Framework is Copyright (c) Vieo, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/packages/service_container/README.md b/packages/service_container/README.md
new file mode 100644
index 0000000..757f4c9
--- /dev/null
+++ b/packages/service_container/README.md
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/service_container/analysis_options.yaml b/packages/service_container/analysis_options.yaml
new file mode 100644
index 0000000..dee8927
--- /dev/null
+++ b/packages/service_container/analysis_options.yaml
@@ -0,0 +1,30 @@
+# This file configures the static analysis results for your project (errors,
+# warnings, and lints).
+#
+# This enables the 'recommended' set of lints from `package:lints`.
+# This set helps identify many issues that may lead to problems when running
+# or consuming Dart code, and enforces writing Dart using a single, idiomatic
+# style and format.
+#
+# If you want a smaller set of lints you can change this to specify
+# 'package:lints/core.yaml'. These are just the most critical lints
+# (the recommended set includes the core lints).
+# The core lints are also what is used by pub.dev for scoring packages.
+
+include: package:lints/recommended.yaml
+
+# Uncomment the following section to specify additional rules.
+
+# linter:
+# rules:
+# - camel_case_types
+
+# analyzer:
+# exclude:
+# - path/to/excluded/files/**
+
+# For more information about the core and recommended set of lints, see
+# https://dart.dev/go/core-lints
+
+# For additional information about configuring this file, see
+# https://dart.dev/guides/language/analysis-options
diff --git a/packages/service_container/doc/.gitkeep b/packages/service_container/doc/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/packages/service_container/example/.gitkeep b/packages/service_container/example/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/packages/service_container/lib/service_container.dart b/packages/service_container/lib/service_container.dart
new file mode 100644
index 0000000..b6ab475
--- /dev/null
+++ b/packages/service_container/lib/service_container.dart
@@ -0,0 +1 @@
+export 'src/container.dart';
diff --git a/packages/service_container/lib/src/bound_method.dart b/packages/service_container/lib/src/bound_method.dart
new file mode 100644
index 0000000..02efe8d
--- /dev/null
+++ b/packages/service_container/lib/src/bound_method.dart
@@ -0,0 +1,107 @@
+import 'package:platform_contracts/contracts.dart';
+import 'package:platform_reflection/mirrors.dart';
+
+/// A utility class for calling methods with dependency injection.
+class BoundMethod {
+ /// Call the given Closure / class@method and inject its dependencies.
+ static dynamic call(ContainerContract container, dynamic callback,
+ [List parameters = const []]) {
+ if (callback is Function) {
+ return callBoundMethod(container, callback, parameters);
+ }
+
+ return callClass(container, callback, parameters);
+ }
+
+ /// Call a string reference to a class@method with dependencies.
+ static dynamic callClass(ContainerContract container, dynamic target,
+ [List parameters = const []]) {
+ target = normalizeMethod(target);
+
+ // If the target is a string, we will assume it is a class name and attempt to resolve it
+ if (target is String) {
+ target = container.make(target);
+ }
+
+ return callBoundMethod(container, target[0], parameters,
+ methodName: target[1]);
+ }
+
+ /// Call a method that has been bound in the container.
+ static dynamic callBoundMethod(
+ ContainerContract container, dynamic target, List parameters,
+ {String? methodName}) {
+ var callable = methodName != null ? [target, methodName] : target;
+
+ var dependencies = getMethodDependencies(container, callable, parameters);
+
+ var reflector = getCallReflector(callable);
+ if (reflector is Function) {
+ return Function.apply(reflector, dependencies);
+ } else if (reflector is InstanceMirrorContract && callable is List) {
+ return reflector.invoke(Symbol(callable[1]), dependencies).reflectee;
+ }
+
+ throw Exception('Unable to call the bound method');
+ }
+
+ /// Normalize the given callback or string into a Class@method String.
+ static dynamic normalizeMethod(dynamic method) {
+ if (method is String && isCallableWithAtSign(method)) {
+ var parts = method.split('@');
+ return parts.length > 1 ? parts : [parts[0], '__invoke'];
+ }
+
+ return method is String ? [method, '__invoke'] : method;
+ }
+
+ /// Get all dependencies for a given method.
+ static List getMethodDependencies(
+ ContainerContract container, dynamic callable, List parameters) {
+ var dependencies = [];
+
+ var reflector = getCallReflector(callable);
+ MethodMirrorContract? methodMirror;
+
+ if (reflector is InstanceMirrorContract && callable is List) {
+ methodMirror = reflector.type.instanceMembers[Symbol(callable[1])];
+ } else if (reflector is MethodMirrorContract) {
+ methodMirror = reflector;
+ }
+
+ methodMirror?.parameters.forEach((parameter) {
+ dependencies
+ .add(addDependencyForCallParameter(container, parameter, parameters));
+ });
+
+ return dependencies;
+ }
+
+ /// Get the proper reflection instance for the given callback.
+ static dynamic getCallReflector(dynamic callable) {
+ if (callable is List) {
+ return reflect(callable[0]);
+ }
+
+ return reflectClass(callable.runtimeType).declarations[Symbol('call')];
+ }
+
+ /// Get the dependency for the given call parameter.
+ static dynamic addDependencyForCallParameter(ContainerContract container,
+ ParameterMirrorContract parameter, List parameters) {
+ if (parameters.isNotEmpty) {
+ return parameters.removeAt(0);
+ }
+
+ if (parameter.isOptional && !parameter.hasDefaultValue) {
+ return null;
+ }
+
+ return container.make(parameter.type.reflectedType.toString());
+ }
+
+ /// Determine if the given string is in Class@method syntax.
+ static bool isCallableWithAtSign(String value) {
+ return value.contains('@');
+ }
+}
diff --git a/packages/service_container/lib/src/container.dart b/packages/service_container/lib/src/container.dart
new file mode 100644
index 0000000..1140664
--- /dev/null
+++ b/packages/service_container/lib/src/container.dart
@@ -0,0 +1,767 @@
+import 'package:platform_contracts/contracts.dart';
+import 'package:platform_reflection/mirrors.dart';
+import 'contextual_binding_builder.dart';
+import 'bound_method.dart';
+
+class _DummyObject {
+ final String className;
+ _DummyObject(this.className);
+
+ @override
+ dynamic noSuchMethod(Invocation invocation) {
+ if (invocation.isMethod) {
+ return (_, __) => null;
+ }
+ return null;
+ }
+}
+
+class Container implements ContainerContract, Map {
+ static Container? _instance;
+
+ final Map _resolved = {};
+ final Map> _bindings = {};
+ final Map _methodBindings = {};
+ final Map _instances = {};
+ final Map> _scopedInstances = {};
+ final Map _aliases = {};
+ final Map> _abstractAliases = {};
+ final Map> _extenders = {};
+ final Map> _tags = {};
+ final List> _buildStack = [];
+ final List